瀏覽代碼

Add test to ctkVTKMatrixWidget and ctkVTKAbstractMatrixWidget

Fix design issues found when creating the test. I still wonder the use of
splitting ctkVTKAbstractMatrixWidget and ctkVTKMatrixWidget
Julien Finet 14 年之前
父節點
當前提交
9ac7c96897

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

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

+ 105 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKMatrixWidgetTest1.cpp

@@ -0,0 +1,105 @@
+/*=========================================================================
+
+  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 <QTimer>
+
+// CTK includes
+#include "ctkVTKMatrixWidget.h"
+
+// VTK includes
+#include <vtkMatrix4x4.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKMatrixWidgetTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  ctkVTKMatrixWidget matrixWidget(0);
+
+  if (matrixWidget.isEnabled())
+    {
+    std::cerr << "No vtkMatrix4x4 provided, should be disabled."
+              << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  vtkMatrix4x4* matrix = vtkMatrix4x4::New();
+
+  matrixWidget.setMatrix(matrix);
+  matrix->Delete();
+
+  if (matrixWidget.matrix() != matrix)
+    {
+    std::cerr << "ctkVTKMatrixWidget::setMatrix() failed."
+              << matrixWidget.matrix() << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  if (matrixWidget.rowCount() != 4 ||
+      matrixWidget.columnCount() != 4)
+    {
+    std::cerr << "ctkVTKMatrixWidget wrong dimension" << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  if (matrixWidget.value(3,3) != 1. ||
+      matrixWidget.value(2,3) != 0.)
+    {
+    std::cerr << "Wrong value" << matrixWidget.value(3,3)
+              << " " << matrixWidget.value(2,3) << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  matrix->SetElement(1, 3, 50.);
+  if (!qFuzzyCompare(matrix->GetElement(1,3), 50.) ||
+      !qFuzzyCompare(matrixWidget.value(1,3), 50.))
+    {
+    std::cerr << "vtkMatrix4x4::SetValue() failed:"
+              << matrix->GetElement(1,3) << " "
+              << matrixWidget.value(1,3) << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  matrixWidget.setValue(2,2, -17.);
+
+  if (!qFuzzyCompare(matrixWidget.value(2,2), -17.) ||
+      !qFuzzyCompare(matrix->GetElement(2,2), -17.))
+    {
+    std::cerr << "ctkVTKMatrixWidget::setValue() failed:"
+              << matrix->GetElement(2,2) << " "
+              << matrixWidget.value(2,2) << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  matrixWidget.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I" )
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+
+  return app.exec();
+}
+

+ 40 - 4
Libs/Visualization/VTK/Widgets/ctkVTKAbstractMatrixWidget.cpp

@@ -47,6 +47,7 @@ void ctkVTKAbstractMatrixWidgetPrivate::init()
 {
   Q_Q(ctkVTKAbstractMatrixWidget);
   this->setParent(q);
+  connect(q, SIGNAL(matrixChanged()), this, SLOT(updateVTKMatrix()));
   this->updateMatrix();
 }
 
@@ -71,15 +72,14 @@ void ctkVTKAbstractMatrixWidgetPrivate::updateMatrix()
 {
   Q_Q(ctkVTKAbstractMatrixWidget);
   // if there is no transform to show/edit, disable the widget
-  q->setEnabled(this->Matrix != 0);
+  q->setEnabled(this->Matrix.GetPointer() != 0);
 
-  if (this->Matrix == 0)
+  if (this->Matrix.GetPointer() == 0)
     {
     q->identity();
     return;
     }
   QVector<double> vector;
-  //todo: fasten the loop
   for (int i=0; i < 4; i++)
     {
     for (int j=0; j < 4; j++)
@@ -91,8 +91,30 @@ void ctkVTKAbstractMatrixWidgetPrivate::updateMatrix()
 }
 
 // --------------------------------------------------------------------------
+void ctkVTKAbstractMatrixWidgetPrivate::updateVTKMatrix()
+{
+  Q_Q(ctkVTKAbstractMatrixWidget);
+  if (this->Matrix.GetPointer() == 0)
+    {
+    return;
+    }
+  double elements[16];
+  int n = 0;
+  for (int i=0; i < 4; i++)
+    {
+    for (int j=0; j < 4; j++)
+      {
+      elements[n++] = q->value(i,j);
+      }
+    }
+  bool blocked = this->qvtkBlockAll(true);
+  this->Matrix->DeepCopy(elements);
+  this->qvtkBlockAll(blocked);
+}
+
+// --------------------------------------------------------------------------
 ctkVTKAbstractMatrixWidget::ctkVTKAbstractMatrixWidget(QWidget* parentVariable)
-  : Superclass(parentVariable)
+  : Superclass(4, 4, parentVariable)
   , d_ptr(new ctkVTKAbstractMatrixWidgetPrivate(*this))
 {
   Q_D(ctkVTKAbstractMatrixWidget);
@@ -112,3 +134,17 @@ void ctkVTKAbstractMatrixWidget::setMatrixInternal(vtkMatrix4x4* matrixVariable)
   Q_D(ctkVTKAbstractMatrixWidget);
   d->setMatrix(matrixVariable);
 }
+
+// --------------------------------------------------------------------------
+void ctkVTKAbstractMatrixWidget::setColumnCount(int newColumnCount)
+{
+  Q_UNUSED(newColumnCount);
+  this->Superclass::setColumnCount(4);
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKAbstractMatrixWidget::setRowCount(int newRowCount)
+{
+  Q_UNUSED(newRowCount);
+  this->Superclass::setRowCount(4);
+}

+ 3 - 0
Libs/Visualization/VTK/Widgets/ctkVTKAbstractMatrixWidget.h

@@ -48,6 +48,9 @@ public:
 protected:
   void setMatrixInternal(vtkMatrix4x4* matrix);
 
+  virtual void setColumnCount(int newColumnCount);
+  virtual void setRowCount(int newRowCount);
+
 protected:
   QScopedPointer<ctkVTKAbstractMatrixWidgetPrivate> d_ptr;
 

+ 6 - 5
Libs/Visualization/VTK/Widgets/ctkVTKAbstractMatrixWidget_p.h

@@ -29,7 +29,7 @@
 #include "ctkVTKAbstractMatrixWidget.h"
 
 // VTK includes
-#include <vtkWeakPointer.h>
+#include <vtkSmartPointer.h>
 
 class vtkMatrix4x4;
 
@@ -42,7 +42,7 @@ class ctkVTKAbstractMatrixWidgetPrivate: public QObject
 protected:
   ctkVTKAbstractMatrixWidget* const q_ptr;
 
-public:  
+public:
   ctkVTKAbstractMatrixWidgetPrivate(ctkVTKAbstractMatrixWidget& object);
   void init();
 
@@ -50,12 +50,13 @@ public:
   vtkMatrix4x4* matrix()const;
 
 public slots:
-  /// 
+  ///
   /// Triggered upon VTK transform modified event
   void updateMatrix();
+  void updateVTKMatrix();
 
 protected:
-  vtkWeakPointer<vtkMatrix4x4> Matrix;
+  vtkSmartPointer<vtkMatrix4x4> Matrix;
 };
 
-#endif 
+#endif

+ 14 - 2
Libs/Widgets/Testing/Cpp/ctkMatrixWidgetTest2.cpp

@@ -175,14 +175,26 @@ int ctkMatrixWidgetTest2(int argc, char * argv [] )
     }
 
   matrixWidget.identity();
-  if (matrixWidget.value(0,0) != 1. ||
-      matrixWidget.value(1,0) != 0.)
+  if (matrixWidget.value(0,0) != 10. ||
+      matrixWidget.value(1,0) != 10.)
     {
     std::cerr << "ctkMatrixWidget::identity() failed:"
               << matrixWidget.value(0,0) << " "
               << matrixWidget.value(1,0) <<std::endl;
     return EXIT_FAILURE;
     }
+
+  matrixWidget.setRange(-100, 100.);
+  matrixWidget.identity();
+
+  if (matrixWidget.value(1,1) != 1. ||
+      matrixWidget.value(0,2) != 0.)
+    {
+    std::cerr << "ctkMatrixWidget::identity() failed:"
+              << matrixWidget.value(1,1) << " "
+              << matrixWidget.value(0,2) <<std::endl;
+    return EXIT_FAILURE;
+    }
  
   matrixWidget.setSingleStep(1.);
   if (matrixWidget.singleStep() != 1.)

+ 19 - 0
Libs/Widgets/ctkMatrixWidget.cpp

@@ -102,6 +102,7 @@ void ctkMatrixWidgetPrivate::init()
   q->setLayout(layout);
 
   // Set parameters for the spinbox
+  // TODO: not sure [-100. 100.] is the right default range
   this->Minimum = -100;
   this->Maximum = 100;
   this->Decimals = 2;
@@ -141,6 +142,12 @@ void ctkMatrixWidgetPrivate::init()
   // The table takes ownership of the prototype.
   this->Table->setItemPrototype(_item);
 
+  QObject::connect(this->Table, SIGNAL(cellChanged(int, int)),
+                   q, SIGNAL(matrixChanged()));
+  /// \todo Wrap model signals to emit signals when the matrix is changed.
+/// Right now you can connect to the signal:
+/// matrixWidget->model()->dataChanged(...)
+
   // Set Read-only
   q->setEditable(true);
 
@@ -408,6 +415,8 @@ void ctkMatrixWidget::setValue(int i, int j, double _value)
 void ctkMatrixWidget::setVector(const QVector<double> & vector)
 {
   Q_D(ctkMatrixWidget);
+  bool blocked = this->blockSignals(true);
+  bool modified = false;
   for (int i=0; i < this->rowCount(); i++)
     {
     for (int j=0; j < this->columnCount(); j++)
@@ -415,7 +424,17 @@ void ctkMatrixWidget::setVector(const QVector<double> & vector)
       double value = qBound(d->Minimum,
                             vector.at(i * this->columnCount() + j),
                             d->Maximum);
+      double oldValue = d->Table->item(i,j)->data(Qt::DisplayRole).toDouble();
       d->Table->item(i,j)->setData(Qt::DisplayRole, QVariant(value));
+      if (oldValue != value)
+        {
+        modified = true;
+        }
       }
     }
+  this->blockSignals(blocked);
+  if (modified)
+    {
+    this->emit matrixChanged();
+    }
 }

+ 5 - 5
Libs/Widgets/ctkMatrixWidget.h

@@ -32,9 +32,6 @@ class ctkMatrixWidgetPrivate;
 
 ///
 /// ctkMatrixWidget is the base class of matrix widgets.
-/// \todo Wrap model signals to emit signals when the matrix is changed.
-/// Right now you can connect to the signal:
-/// matrixWidget->model()->dataChanged(...)
 class CTK_WIDGETS_EXPORT ctkMatrixWidget: public QWidget
 {
   Q_OBJECT
@@ -59,12 +56,12 @@ public:
   /// Set the number of columns of the matrix
   /// \sa rowCount, setRowCount
   int columnCount()const;
-  void setColumnCount(int newColumnCount);
+  virtual void setColumnCount(int newColumnCount);
 
   /// Set the number of rows of the matrix
   /// \sa columnCount, setColumnCount
   int rowCount()const;
-  void setRowCount(int newRowCount);
+  virtual void setRowCount(int newRowCount);
 
   ///
   /// Set / Get values of the matrix
@@ -130,6 +127,9 @@ public slots:
   /// Reset the matrix to identity
   void identity();
 
+signals:
+  void matrixChanged();
+
 protected:
   virtual void resizeEvent(QResizeEvent* event);