Ver código fonte

Allow user to set/reset the range in ctkVTKHistogram

Previously, the range was tied to the data array range. Now with the new
method, the user can change the range of the histogram easily.
When the range is changed, the histogram will be recomputed if the number
of bins changes.
Johan Andruejol 9 anos atrás
pai
commit
b21c94b894

+ 12 - 2
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKHistogramTest2.cpp

@@ -32,6 +32,9 @@ int ctkVTKHistogramTest2( int argc, char * argv [])
   rgbDataArray->InsertNextTuple3(1000, 143, -1412);
   rgbDataArray->InsertNextTuple3(1000, 143, -1412);
   rgbDataArray->InsertNextTuple3(-543, 210,   151);
   rgbDataArray->InsertNextTuple3(-543, 210,   151);
   rgbDataArray->InsertNextTuple3(  -1, 210,    10);
   rgbDataArray->InsertNextTuple3(  -1, 210,    10);
+
+  // Generate histogram on the Green values
+  rgbHistogram.setComponent(1);
   rgbHistogram.setDataArray(rgbDataArray);
   rgbHistogram.setDataArray(rgbDataArray);
   if (rgbHistogram.dataArray() != rgbDataArray)
   if (rgbHistogram.dataArray() != rgbDataArray)
     {
     {
@@ -41,8 +44,15 @@ int ctkVTKHistogramTest2( int argc, char * argv [])
     return EXIT_FAILURE;
     return EXIT_FAILURE;
     }
     }
 
 
-  // Generate histogram on the Green values
-  rgbHistogram.setComponent(1);
+  double range[2], expectedRange[2] = {50.0, 211.0};
+  rgbHistogram.range(range[0], range[1]);
+  if (range[0] != expectedRange[0] && range[1] != expectedRange[1])
+    {
+    std::cerr << "Bad range: " << range[0] << " " << range[1] << std::endl
+              << " expected: " << expectedRange[0] << " " << expectedRange[1]
+              << std::endl;
+    return EXIT_FAILURE;
+    }
 
 
   //------Test build---------------------------------
   //------Test build---------------------------------
   rgbHistogram.build();
   rgbHistogram.build();

+ 72 - 27
Libs/Visualization/VTK/Widgets/ctkVTKHistogram.cpp

@@ -73,27 +73,7 @@ int ctkVTKHistogramPrivate::computeNumberOfBins()const
     {
     {
     return -1;
     return -1;
     }
     }
-  
-  if (this->DataArray->GetDataType() == VTK_CHAR ||
-      this->DataArray->GetDataType() == VTK_SIGNED_CHAR ||
-      this->DataArray->GetDataType() == VTK_UNSIGNED_CHAR)
-    {
-    this->Range[0] = this->DataArray->GetDataTypeMin();
-    this->Range[1] = this->DataArray->GetDataTypeMax();
-    }
-  else
-    {
-    this->DataArray->GetRange(this->Range, this->Component);
-    if (this->DataArray->GetDataType() == VTK_FLOAT ||
-        this->DataArray->GetDataType() == VTK_DOUBLE)
-      {
-      this->Range[1] += 0.01;
-      }
-    //else
-    //  {
-    //  this->Range[1] += 1;
-    //  }
-    }
+
   if (this->UserNumberOfBins > 0)
   if (this->UserNumberOfBins > 0)
     {
     {
     return this->UserNumberOfBins;
     return this->UserNumberOfBins;
@@ -131,26 +111,85 @@ int ctkVTKHistogram::count()const
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void ctkVTKHistogram::range(qreal& minRange, qreal& maxRange)const
+void ctkVTKHistogram::setRange(qreal minRange, qreal maxRange)
 {
 {
   Q_D(const ctkVTKHistogram);
   Q_D(const ctkVTKHistogram);
   if (d->DataArray.GetPointer() == 0)
   if (d->DataArray.GetPointer() == 0)
     {
     {
     //Q_ASSERT(d->DataArray.GetPointer());
     //Q_ASSERT(d->DataArray.GetPointer());
-    logger.warn("no dataArray");
+    logger.warn("no data array. range will be reset when setting array.");
     minRange = 1.; // set incorrect values
     minRange = 1.; // set incorrect values
     maxRange = 0.;
     maxRange = 0.;
     return;
     return;
     }
     }
-  if (d->Range[0] == d->Range[1])
+  if (minRange >= maxRange)
+    {
+    //Q_ASSERT(d->DataArray.GetPointer());
+    logger.warn("minRange >= maxRange");
+    qreal pivot = minRange;
+    minRange = maxRange;
+    maxRange = pivot;
+    }
+
+  int numberOfBinsBefore = d->computeNumberOfBins();
+  d->Range[0] = minRange;
+  d->Range[1] = maxRange;
+  if (d->computeNumberOfBins() != numberOfBinsBefore)
     {
     {
-    minRange = d->DataArray->GetDataTypeMin();
-    maxRange = d->DataArray->GetDataTypeMax();
+    this->build();
+    }
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKHistogram::range(qreal& minRange, qreal& maxRange)const
+{
+  Q_D(const ctkVTKHistogram);
+  if (d->DataArray.GetPointer() == 0)
+    {
+    //Q_ASSERT(d->DataArray.GetPointer());
+    logger.warn("no dataArray");
+    minRange = 1.; // set incorrect values
+    maxRange = 0.;
     return;
     return;
     }
     }
   minRange = d->Range[0];
   minRange = d->Range[0];
   maxRange = d->Range[1];
   maxRange = d->Range[1];
-} 
+}
+
+//-----------------------------------------------------------------------------
+void ctkVTKHistogram::resetRange()
+{
+  Q_D(ctkVTKHistogram);
+  if (d->DataArray.GetPointer() == 0)
+    {
+    //Q_ASSERT(d->DataArray.GetPointer());
+    logger.warn("no dataArray");
+    d->Range[0] = 1.; // set incorrect values
+    d->Range[1] = 0.;
+    return;
+    }
+
+  if (d->DataArray->GetDataType() == VTK_CHAR ||
+      d->DataArray->GetDataType() == VTK_SIGNED_CHAR ||
+      d->DataArray->GetDataType() == VTK_UNSIGNED_CHAR)
+    {
+    d->Range[0] = d->DataArray->GetDataTypeMin();
+    d->Range[1] = d->DataArray->GetDataTypeMax();
+    }
+  else
+    {
+    d->DataArray->GetRange(d->Range, d->Component);
+    if (d->DataArray->GetDataType() == VTK_FLOAT ||
+        d->DataArray->GetDataType() == VTK_DOUBLE)
+      {
+      d->Range[1] += 0.01;
+      }
+    //else
+    //  {
+    //  this->Range[1] += 1;
+    //  }
+    }
+}
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 QVariant ctkVTKHistogram::minValue()const
 QVariant ctkVTKHistogram::minValue()const
@@ -203,7 +242,13 @@ int ctkVTKHistogram::posToIndex(qreal pos)const
 void ctkVTKHistogram::setDataArray(vtkDataArray* newDataArray)
 void ctkVTKHistogram::setDataArray(vtkDataArray* newDataArray)
 {
 {
   Q_D(ctkVTKHistogram);
   Q_D(ctkVTKHistogram);
+  if (newDataArray == d->DataArray)
+    {
+    return;
+    }
+
   d->DataArray = newDataArray;
   d->DataArray = newDataArray;
+  this->resetRange();
   this->qvtkReconnect(d->DataArray,vtkCommand::ModifiedEvent,
   this->qvtkReconnect(d->DataArray,vtkCommand::ModifiedEvent,
                       this, SIGNAL(changed()));
                       this, SIGNAL(changed()));
   emit changed();
   emit changed();

+ 10 - 1
Libs/Visualization/VTK/Widgets/ctkVTKHistogram.h

@@ -52,8 +52,15 @@ public:
   /// Returns the number of bins. Returns 0 until build() is called.
   /// Returns the number of bins. Returns 0 until build() is called.
   virtual int count()const;
   virtual int count()const;
 
 
-  /// Please note that range only works if you have at least set an array.
+  // Set/Get the range of the histogram.
+  // Please note that after an array is set, the range will be reset.
+  // \sa resetRange()
+  virtual void setRange(qreal minRang, qreal maxRange);
   virtual void range(qreal& minRange, qreal& maxRange)const;
   virtual void range(qreal& minRange, qreal& maxRange)const;
+
+  // Reset the range to the array's range.
+  virtual void resetRange();
+
   virtual QVariant minValue()const;
   virtual QVariant minValue()const;
   virtual QVariant maxValue()const;
   virtual QVariant maxValue()const;
 
 
@@ -63,6 +70,8 @@ public:
   void setComponent(int component);
   void setComponent(int component);
   int component()const;
   int component()const;
 
 
+  // Set the number of bins to use in the histogram. If this is set,
+  // the range will be ignored.
   int numberOfBins()const;
   int numberOfBins()const;
   void setNumberOfBins(int number);
   void setNumberOfBins(int number);