瀏覽代碼

Merge pull request #652 from vovythevov/HistogramSetRange

Allow user to set/reset the range in ctkVTKHistogram
Jean-Christophe Fillion-Robin 8 年之前
父節點
當前提交
8e62310aeb

+ 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(-543, 210,   151);
   rgbDataArray->InsertNextTuple3(  -1, 210,    10);
+
+  // Generate histogram on the Green values
+  rgbHistogram.setComponent(1);
   rgbHistogram.setDataArray(rgbDataArray);
   if (rgbHistogram.dataArray() != rgbDataArray)
     {
@@ -41,8 +44,15 @@ int ctkVTKHistogramTest2( int argc, char * argv [])
     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---------------------------------
   rgbHistogram.build();

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

@@ -73,27 +73,7 @@ int ctkVTKHistogramPrivate::computeNumberOfBins()const
     {
     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)
     {
     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);
   if (d->DataArray.GetPointer() == 0)
     {
     //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
     maxRange = 0.;
     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;
     }
   minRange = d->Range[0];
   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
@@ -203,7 +242,13 @@ int ctkVTKHistogram::posToIndex(qreal pos)const
 void ctkVTKHistogram::setDataArray(vtkDataArray* newDataArray)
 {
   Q_D(ctkVTKHistogram);
+  if (newDataArray == d->DataArray)
+    {
+    return;
+    }
+
   d->DataArray = newDataArray;
+  this->resetRange();
   this->qvtkReconnect(d->DataArray,vtkCommand::ModifiedEvent,
                       this, SIGNAL(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.
   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;
+
+  // Reset the range to the array's range.
+  virtual void resetRange();
+
   virtual QVariant minValue()const;
   virtual QVariant maxValue()const;
 
@@ -63,6 +70,8 @@ public:
   void setComponent(int component);
   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;
   void setNumberOfBins(int number);