瀏覽代碼

Add ctkVTKDataSetModel for vtkDataSet arrays

Very naive and basic version. To be improved.
Julien Finet 14 年之前
父節點
當前提交
6a9f49d09b

+ 3 - 0
Libs/Visualization/VTK/Widgets/CMakeLists.txt

@@ -22,6 +22,8 @@ SET(KIT_SRCS
   ctkVTKAbstractMatrixWidget.cpp
   ctkVTKAbstractMatrixWidget.h
   ctkVTKAbstractMatrixWidget_p.h
+  ctkVTKDataSetModel.cpp
+  ctkVTKDataSetModel.h
   ctkVTKMatrixWidget.cpp
   ctkVTKMatrixWidget.h
   ctkVTKRenderView.cpp
@@ -43,6 +45,7 @@ SET(KIT_SRCS
 # Headers that should run through moc
 SET(KIT_MOC_SRCS
   ctkVTKAbstractMatrixWidget_p.h
+  ctkVTKDataSetModel.h
   ctkVTKMatrixWidget.h
   ctkVTKRenderView.h
   ctkVTKRenderView_p.h

+ 2 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -4,6 +4,7 @@ SET(KIT ${PROJECT_NAME})
 # Tests
 #
 SET(TEST_SOURCES
+  ctkVTKDataSetModelTest1.cpp
   ctkVTKMatrixWidgetTest1.cpp
   ctkTransferFunctionBarsItemTest1.cpp
   ctkTransferFunctionViewTest1.cpp
@@ -61,6 +62,7 @@ ENDMACRO( SIMPLE_TEST  )
 # Add Tests
 #
 
+SIMPLE_TEST( ctkVTKDataSetModelTest1 )
 SIMPLE_TEST( ctkVTKMatrixWidgetTest1 )
 SIMPLE_TEST( ctkTransferFunctionBarsItemTest1 )
 SIMPLE_TEST( ctkTransferFunctionViewTest1 )

+ 68 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKDataSetModelTest1.cpp

@@ -0,0 +1,68 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QComboBox>
+#include <QTimer>
+#include <QDebug>
+
+// CTK includes
+#include "ctkVTKDataSetModel.h"
+
+// VTK includes
+#include <vtkCellData.h>
+#include <vtkFloatArray.h>
+#include <vtkIntArray.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKDataSetModelTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  vtkSmartPointer<vtkPolyData> dataSet =
+      vtkSmartPointer<vtkPolyData>::New();
+  vtkSmartPointer<vtkIntArray> ints = vtkSmartPointer<vtkIntArray>::New();
+  ints->SetName("Ints");
+  dataSet->GetPointData()->AddArray(ints);
+  vtkSmartPointer<vtkFloatArray> floats= vtkSmartPointer<vtkFloatArray>::New();
+  floats->SetName("Floats");
+  dataSet->GetCellData()->AddArray(floats);
+  
+  ctkVTKDataSetModel dataSetModel;
+  dataSetModel.setDataSet(dataSet);
+  
+  QComboBox comboBox;
+  comboBox.setModel(&dataSetModel);
+  comboBox.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(1000, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 344 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetModel.cpp

@@ -0,0 +1,344 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QDebug>
+
+// CTK includes
+#include "ctkVTKDataSetModel.h"
+
+// VTK includes
+#include <vtkCellData.h>
+#include <vtkSmartPointer.h>
+#include <vtkDataArray.h>
+#include <vtkDataSet.h>
+#include <vtkPointData.h>
+
+class ctkVTKDataSetModelPrivate
+{
+  Q_DECLARE_PUBLIC(ctkVTKDataSetModel);
+protected:
+  ctkVTKDataSetModel* const q_ptr;
+public:
+  ctkVTKDataSetModelPrivate(ctkVTKDataSetModel& object);
+  virtual ~ctkVTKDataSetModelPrivate();
+  void init();
+  //void listenDataArrayModifiedEvent();
+
+  vtkSmartPointer<vtkDataSet> DataSet;
+  bool ListenDataArrayModifiedEvent;
+};
+
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModelPrivate::ctkVTKDataSetModelPrivate(ctkVTKDataSetModel& object)
+  : q_ptr(&object)
+{
+  this->ListenDataArrayModifiedEvent = false;
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModelPrivate::~ctkVTKDataSetModelPrivate()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModelPrivate::init()
+{
+  Q_Q(ctkVTKDataSetModel);
+  q->setColumnCount(1);
+  
+  QObject::connect(q, SIGNAL(itemChanged(QStandardItem*)),
+                   q, SLOT(onItemChanged(QStandardItem*)));
+}
+/*
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModelPrivate::listenDataArrayModifiedEvent()
+{
+  Q_Q(ctkVTKDataSetModel);
+  q->qvtkDisconnect(0, vtkCommand::ModifiedEvent, q, SLOT(onArrayModified(vtkObject*)));
+  if (!this->ListenDataArrayModifiedEvent)
+    {
+    return;
+    }
+  const int count = q->rowCount();
+  for (int i = 0; i < count; ++i)
+    {
+    q->qvtkConnect(q->arrayFromIndex(q->index(i,0)),vtkCommand::ModifiedEvent,
+                   q, SLOT(onMRMLNodeModified(vtkObject*)));
+    }
+}
+*/
+
+//------------------------------------------------------------------------------
+// ctkVTKDataSetModel
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::ctkVTKDataSetModel(QObject *_parent)
+  : QStandardItemModel(_parent)
+  , d_ptr(new ctkVTKDataSetModelPrivate(*this))
+{
+  Q_D(ctkVTKDataSetModel);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::ctkVTKDataSetModel(ctkVTKDataSetModelPrivate* pimpl, QObject *parentObject)
+  : QStandardItemModel(parentObject)
+  , d_ptr(pimpl)
+{
+  Q_D(ctkVTKDataSetModel);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::~ctkVTKDataSetModel()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::setDataSet(vtkDataSet* dataSet)
+{
+  Q_D(ctkVTKDataSetModel);
+  this->qvtkReconnect(d->DataSet, dataSet, vtkCommand::ModifiedEvent,
+                      this, SLOT(onDataSetModified(vtkObject*)) );
+  d->DataSet = dataSet;
+  this->updateDataSet();
+}
+
+//------------------------------------------------------------------------------
+vtkDataSet* ctkVTKDataSetModel::dataSet()const
+{
+  Q_D(const ctkVTKDataSetModel);
+  return d->DataSet;
+}
+
+//------------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetModel::arrayFromItem(QStandardItem* dataArrayItem)const
+{
+  Q_D(const ctkVTKDataSetModel);
+  if (dataArrayItem == 0 || dataArrayItem == this->invisibleRootItem())
+    {
+    return 0;
+    }
+  QVariant dataArrayPointer = dataArrayItem->data(ctkVTK::PointerRole);
+  Q_ASSERT(dataArrayPointer.isValid());
+  vtkDataArray* dataArray = static_cast<vtkDataArray*>(
+    reinterpret_cast<void *>(dataArrayPointer.toLongLong()));
+  Q_ASSERT(dataArray);
+  return dataArray;
+}
+
+//------------------------------------------------------------------------------
+QStandardItem* ctkVTKDataSetModel::itemFromArray(vtkDataArray* dataArray, int column)const
+{
+  if (dataArray == 0)
+    {
+    return 0;
+    }
+  QModelIndexList indexes = this->match(this->index(-1,-1), ctkVTK::PointerRole,
+                                      reinterpret_cast<long long>(dataArray), 1,
+                                      Qt::MatchExactly | Qt::MatchRecursive);
+  while (indexes.size())
+    {
+    if (indexes[0].column() == column)
+      {
+      return this->itemFromIndex(indexes[0]);
+      }
+    indexes = this->match(indexes[0], ctkVTK::PointerRole,
+                          reinterpret_cast<long long>(dataArray), 1,
+                          Qt::MatchExactly | Qt::MatchRecursive);
+    }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+QModelIndexList ctkVTKDataSetModel::indexes(vtkDataArray* dataArray)const
+{
+  return this->match(this->index(-1,-1), ctkVTK::PointerRole,
+                     QVariant::fromValue(reinterpret_cast<long long>(dataArray)),
+                     -1, Qt::MatchExactly | Qt::MatchRecursive);
+}
+
+/*
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::setListenArrayModifiedEvent(bool listen)
+{
+  Q_D(ctkVTKDataSetModel);
+  if (d->ListenArrayModifiedEvent == listen)
+    {
+    return;
+    }
+  d->ListenArrayModifiedEvent = listen;
+  d->listenArrayModifiedEvent();
+}
+
+//------------------------------------------------------------------------------
+bool ctkVTKDataSetModel::listenNodeModifiedEvent()const
+{
+  Q_D(const ctkVTKDataSetModel);
+  return d->ListenNodeModifiedEvent;
+}
+*/
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateDataSet()
+{
+  Q_D(ctkVTKDataSetModel);
+  this->setRowCount(0);
+
+  if (d->DataSet.GetPointer() == 0)
+    {
+    return;
+    }
+
+  // Populate scene with nodes
+  this->populateDataSet();
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::populateDataSet()
+{
+  Q_D(ctkVTKDataSetModel);
+  Q_ASSERT(d->DataSet);
+
+  for (int p = 0; p < d->DataSet->GetPointData()->GetNumberOfArrays(); ++p)
+    {
+    this->insertArray(d->DataSet->GetPointData()->GetArray(p));
+    }
+
+  for (int p = 0; p < d->DataSet->GetCellData()->GetNumberOfArrays(); ++p)
+    {
+    this->insertArray(d->DataSet->GetCellData()->GetArray(p));
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::insertArray(vtkDataArray* dataArray)
+{
+  this->insertArray(dataArray, this->rowCount());
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::insertArray(vtkDataArray* dataArray, int row)
+{
+  Q_D(ctkVTKDataSetModel);
+  Q_ASSERT(vtkDataArray::SafeDownCast(dataArray));
+
+  QList<QStandardItem*> items;
+  for (int i= 0; i < this->columnCount(); ++i)
+    {
+    QStandardItem* newArrayItem = new QStandardItem();
+    this->updateItemFromArray(newArrayItem, dataArray, i);
+    items.append(newArrayItem);
+    }
+  this->insertRow(row,items);
+  // TODO: don't listen to nodes that are hidden from editors ?
+  if (d->ListenDataArrayModifiedEvent)
+    {
+    qvtkConnect(dataArray, vtkCommand::ModifiedEvent,
+                this, SLOT(onArrayModified(vtkObject*)));
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateItemFromArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  item->setData(QVariant::fromValue(reinterpret_cast<long long>(dataArray)), ctkVTK::PointerRole);
+  switch (column)
+    {
+    case 0:
+      item->setText(QString(dataArray->GetName()));
+      break;
+    default:
+      Q_ASSERT(column == 0);
+      break;
+    }
+}
+
+//------------------------------------------------------------------------------
+/*
+void ctkVTKDataSetModel::updateItemFromPointsArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  this->updateItemFromArray(item, dataArray, column);
+  switch (column)
+    {
+    case 0:
+      item->setIcon();
+      break;
+    default:
+      Q_ASSERT(column == 0)
+      break;
+    }
+}
+
+//------------------------------------------------------------------------------
+/*
+void ctkVTKDataSetModel::updateItemFromCellsArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  this->updateItemFromArray(item, dataArray, column);
+  switch (column)
+    {
+    case 0:
+      item->setIcon();
+      break;
+    default:
+      Q_ASSERT(column == 0)
+      break;
+    }
+}
+
+*/
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateArrayFromItem(vtkDataArray* dataArray, QStandardItem* item)
+{
+  if (item->column() == 0)
+    {
+    dataArray->SetName(item->text().toLatin1());
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onDataSetModified(vtkObject* dataSet)
+{
+  this->updateDataSet();
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onArrayModified(vtkObject* array)
+{
+  Q_D(ctkVTKDataSetModel);
+  vtkDataArray* dataArray = vtkDataArray::SafeDownCast(array);
+  Q_ASSERT(dataArray);
+  QModelIndexList arrayIndexes = this->indexes(dataArray);
+
+  foreach (QModelIndex index, arrayIndexes)
+    {
+    QStandardItem* item = this->itemFromIndex(index);
+    this->updateItemFromArray(item, dataArray, item->column());
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onItemChanged(QStandardItem * item)
+{
+  vtkDataArray* dataArray = this->arrayFromItem(item);
+  Q_ASSERT(dataArray);
+  this->updateArrayFromItem(dataArray, item);
+}

+ 97 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetModel.h

@@ -0,0 +1,97 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKDataSetModel_h
+#define __ctkVTKDataSetModel_h
+
+// Qt includes
+#include <QStandardItemModel>
+
+// CTK includes
+#include <ctkVTKObject.h>
+
+// CTK includes
+#include "ctkVisualizationVTKWidgetsExport.h"
+
+class vtkDataSet;
+class vtkDataArray;
+
+namespace ctkVTK
+{
+ enum ItemDataRole {
+   PointerRole = Qt::UserRole + 1
+ };
+};
+
+class ctkVTKDataSetModelPrivate;
+
+//------------------------------------------------------------------------------
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKDataSetModel
+  : public QStandardItemModel
+{
+  Q_OBJECT
+  QVTK_OBJECT
+
+public:
+  typedef QStandardItemModel Superclass;
+  ctkVTKDataSetModel(QObject *parent=0);
+  virtual ~ctkVTKDataSetModel();
+
+  virtual void setDataSet(vtkDataSet* dataSet);
+  vtkDataSet* dataSet()const;
+
+  /// Return the vtkDataArray associated to the index.
+  /// 0 if the index doesn't contain a vtkDataArray
+  inline vtkDataArray* arrayFromIndex(const QModelIndex& arrayIndex)const;
+  vtkDataArray* arrayFromItem(QStandardItem* nodeItem)const;
+  QStandardItem* itemFromArray(vtkDataArray* dataArray, int column = 0)const;
+  QModelIndexList indexes(vtkDataArray* dataArray)const;
+
+protected slots:
+  void onDataSetModified(vtkObject* dataSet);
+  void onArrayModified(vtkObject* dataArray);
+  void onItemChanged(QStandardItem * item);
+
+protected:
+
+  ctkVTKDataSetModel(ctkVTKDataSetModelPrivate* pimpl, QObject *parent=0);
+
+  virtual void insertArray(vtkDataArray* dataArray);
+  virtual void insertArray(vtkDataArray* dataArray, int row);
+  virtual void updateItemFromArray(QStandardItem* item, vtkDataArray* dataArray, int column);
+  virtual void updateArrayFromItem(vtkDataArray* dataArray, QStandardItem* item);
+  virtual void updateDataSet();
+  virtual void populateDataSet();
+
+protected:
+  QScopedPointer<ctkVTKDataSetModelPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkVTKDataSetModel);
+  Q_DISABLE_COPY(ctkVTKDataSetModel);
+};
+
+// -----------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetModel::arrayFromIndex(const QModelIndex &nodeIndex)const
+{
+  return this->arrayFromItem(this->itemFromIndex(nodeIndex));
+}
+
+#endif