Selaa lähdekoodia

Merge pull request #774 from tcoulange/options_color_widget_height

Add options to handle color widget height
Julien Finet 7 vuotta sitten
vanhempi
commit
790a0586fb

+ 1 - 0
Libs/Visualization/VTK/Core/CMakeLists.txt

@@ -70,6 +70,7 @@ if(${VTK_VERSION_MAJOR} GREATER 5)
     vtkCommonCore
     vtkCommonDataModel
     vtkCommonSystem
+    vtkFiltersStatistics
     vtkIOImage
     vtkInteractionStyle
     vtkRenderingAnnotation

+ 12 - 0
Libs/Visualization/VTK/Core/vtkScalarsToColorsContextItem.cpp

@@ -110,6 +110,18 @@ vtkScalarsToColorsContextItem::~vtkScalarsToColorsContextItem()
 }
 
 // ----------------------------------------------------------------------------
+void vtkScalarsToColorsContextItem::SetLeftAxisMode(int mode)
+{
+  this->HistogramChart->SetLeftAxisMode(mode);
+}
+
+// ----------------------------------------------------------------------------
+int vtkScalarsToColorsContextItem::GetLeftAxisMode()
+{
+  return this->HistogramChart->GetLeftAxisMode();
+}
+
+// ----------------------------------------------------------------------------
 void vtkScalarsToColorsContextItem::CopyColorTransferFunction(
   vtkScalarsToColors* ctf)
 {

+ 6 - 0
Libs/Visualization/VTK/Core/vtkScalarsToColorsContextItem.h

@@ -46,6 +46,12 @@ class CTK_VISUALIZATION_VTK_CORE_EXPORT vtkScalarsToColorsContextItem
 public:
   static vtkScalarsToColorsContextItem* New();
 
+  /// Set/Get the left axis mode.
+  /// This controls the axis range computation.
+  /// \see vtkScalarsToColorsHistogramChart::SetLeftAxisMode
+  void SetLeftAxisMode(int mode);
+  int GetLeftAxisMode();
+
   /// Copy the color transfer function as a vtkDiscretizableColorTransferFunction
   void CopyColorTransferFunction(vtkScalarsToColors* ctf);
   vtkDiscretizableColorTransferFunction* GetDiscretizableColorTransferFunction();

+ 57 - 0
Libs/Visualization/VTK/Core/vtkScalarsToColorsHistogramChart.cpp

@@ -20,6 +20,9 @@
 #include "vtkScalarsToColorsHistogramChart.h"
 
 #include <vtkAxis.h>
+#include <vtkDescriptiveStatistics.h>
+#include <vtkMultiBlockDataSet.h>
+#include <vtkNew.h>
 #include <vtkObjectFactory.h>
 #include <vtkPen.h>
 #include <vtkPlotBar.h>
@@ -49,6 +52,8 @@ vtkScalarsToColorsHistogramChart::vtkScalarsToColorsHistogramChart()
 
   this->GetAxis(vtkAxis::BOTTOM)->SetBehavior(vtkAxis::FIXED);
 
+  this->LeftAxisMode = VTK_AUTO;
+
   this->SetBarWidthFraction(1.0);
 
   // Set up the plot bar
@@ -65,9 +70,61 @@ vtkScalarsToColorsHistogramChart::~vtkScalarsToColorsHistogramChart()
 }
 
 // ----------------------------------------------------------------------------
+void vtkScalarsToColorsHistogramChart::SetLeftAxisMode(int mode)
+{
+  switch (mode)
+  {
+    case vtkScalarsToColorsHistogramChart::VTK_AUTO:
+      this->GetAxis(vtkAxis::LEFT)->SetBehavior(vtkAxis::AUTO);
+      break;
+    case vtkScalarsToColorsHistogramChart::MAXIMUM:
+    case vtkScalarsToColorsHistogramChart::MEAN_PLUS_THREE_SIGMA:
+      this->GetAxis(vtkAxis::LEFT)->SetBehavior(vtkAxis::FIXED);
+      break;
+    default:
+      return;
+  }
+
+  this->LeftAxisMode = mode;
+}
+
+// ----------------------------------------------------------------------------
+int vtkScalarsToColorsHistogramChart::GetLeftAxisMode()
+{
+  return this->LeftAxisMode;
+}
+
+// ----------------------------------------------------------------------------
 void vtkScalarsToColorsHistogramChart::SetHistogramInputData(vtkTable* table,
     const char* xAxisColumn, const char* yAxisColumn)
 {
+  if (this->LeftAxisMode == MAXIMUM
+   || this->LeftAxisMode == MEAN_PLUS_THREE_SIGMA)
+  {
+    // compute histogram mean and standard deviation
+    vtkNew<vtkDescriptiveStatistics> statisticsFilter;
+    statisticsFilter->SetInputData(table);
+    statisticsFilter->AddColumn(yAxisColumn);
+    statisticsFilter->Update();
+    vtkMultiBlockDataSet* stats = vtkMultiBlockDataSet::SafeDownCast(
+      statisticsFilter->GetOutputDataObject(vtkStatisticsAlgorithm::OUTPUT_MODEL));
+    vtkTable* statsPrimary = vtkTable::SafeDownCast(stats->GetBlock(0));
+    vtkTable* statsDerived = vtkTable::SafeDownCast(stats->GetBlock(1));
+
+    // update axis
+    if (this->LeftAxisMode == MAXIMUM)
+    {
+      double max = statsPrimary->GetValueByName(0, "Maximum").ToDouble();
+      this->GetAxis(vtkAxis::LEFT)->SetUnscaledRange(0, max);
+    }
+    else if (this->LeftAxisMode == MEAN_PLUS_THREE_SIGMA)
+    {
+      double mean = statsPrimary->GetValueByName(0, "Mean").ToDouble();
+      double sigma = statsDerived->GetValueByName(0, "Standard Deviation").ToDouble();
+      this->GetAxis(vtkAxis::LEFT)->SetUnscaledRange(0, mean + 3 * sigma);
+    }
+  }
+
   this->HistogramPlotBar->SetInputData(table, xAxisColumn, yAxisColumn);
   this->SelectColorArray(xAxisColumn);
   this->RecalculateBounds();

+ 16 - 0
Libs/Visualization/VTK/Core/vtkScalarsToColorsHistogramChart.h

@@ -37,6 +37,21 @@ public:
   vtkTypeMacro(vtkScalarsToColorsHistogramChart, vtkChartXY)
   static vtkScalarsToColorsHistogramChart* New();
 
+  enum
+  {
+    VTK_AUTO, // VTK auto scaling: scale the axis to view all data that is visible.
+    MAXIMUM, // Scale the axis to the maximum value of histogram.
+    MEAN_PLUS_THREE_SIGMA // Scale the axis to "mean + 3 * sigma".
+  };
+
+  /// Set/Get the left axis mode, which controls the axis range computation.
+  ///   VTK_AUTO: VTK auto scaling. Scale the axis to view all data that is visible.
+  ///   MAXIMUM: Scale the axis to the maximum value of histogram.
+  ///   MEAN_PLUS_THREE_SIGMA: Scale the axis to "mean + 3 * sigma".
+  /// Default mode is VTK_AUTO.
+  void SetLeftAxisMode(int mode);
+  int GetLeftAxisMode();
+
   /// Set input for histogram
   virtual void SetHistogramInputData(vtkTable* table, const char* xAxisColumn,
     const char* yAxisColumn);
@@ -52,6 +67,7 @@ public:
 
 protected:
   vtkNew<vtkPlotBar> HistogramPlotBar;
+  int LeftAxisMode;
 
 private:
   vtkScalarsToColorsHistogramChart();

+ 3 - 1
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -40,7 +40,7 @@ if(CTK_USE_CHARTS)
   set(TEST_SOURCES
       ctkVTKChartViewTest1.cpp
       ctkVTKVolumePropertyWidgetTest1.cpp
-	  ctkVTKDiscretizableColorTransferWidgetTest1.cpp
+      ctkVTKDiscretizableColorTransferWidgetTest1.cpp
       ctkVTKScalarsToColorsViewTest1.cpp
       ctkVTKScalarsToColorsViewTest2.cpp
       ctkVTKScalarsToColorsViewTest3.cpp
@@ -176,6 +176,7 @@ SIMPLE_TEST( ctkTransferFunctionViewTest5 )
 if(CTK_USE_CHARTS)
   SIMPLE_TEST( ctkVTKChartViewTest1 )
   SIMPLE_TEST( ctkVTKVolumePropertyWidgetTest1 )
+  SIMPLE_TEST( ctkVTKDiscretizableColorTransferWidgetTest1 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest1 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest2 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest3 )
@@ -185,6 +186,7 @@ if(CTK_USE_CHARTS)
   SIMPLE_TEST( ctkVTKScalarsToColorsWidgetTest3 )
 endif()
 SIMPLE_TEST( ctkVTKRenderViewTest1 )
+SIMPLE_TEST( ctkVTKScalarsToColorsComboBoxTest1 )
 SIMPLE_TEST( ctkVTKSliceViewTest1 )
 SIMPLE_TEST( ctkVTKSurfaceMaterialPropertyWidgetTest1 )
 SIMPLE_TEST( ctkVTKTextPropertyWidgetTest1 )

+ 12 - 1
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKDiscretizableColorTransferWidgetTest1.cpp

@@ -25,11 +25,13 @@ limitations under the License.
 // CTK includes
 #include "ctkVTKDiscretizableColorTransferWidget.h"
 #include "ctkVTKScalarsToColorsComboBox.h"
+#include "vtkScalarsToColorsHistogramChart.h"
 
 // VTK includes
 #include <vtkDiscretizableColorTransferFunction.h>
 #include <vtkNew.h>
 #include <vtkPiecewiseFunction.h>
+#include <vtkRTAnalyticSource.h>
 
 //-----------------------------------------------------------------------------
 int ctkVTKDiscretizableColorTransferWidgetTest1(int argc, char * argv[])
@@ -59,9 +61,18 @@ int ctkVTKDiscretizableColorTransferWidgetTest1(int argc, char * argv[])
   ctf0->AddRGBPoint(0.0, 1.0, 0.0, 1.0);
   ctf0->AddRGBPoint(255.0, 0.0, 1.0, 0.0);
 
+  /// Create an image to test the widget histogram
+  vtkNew<vtkRTAnalyticSource> imageSource;
+  imageSource->SetWholeExtent(0, 9,
+                              0, 9,
+                              0, 9);
+
   /// Discretizable transfer function widget
   ctkVTKDiscretizableColorTransferWidget mWidget;
-  mWidget.setColorTransferFunction(dctf0.Get());
+  mWidget.copyColorTransferFunction(dctf0.Get());
+  mWidget.setHistogramConnection(imageSource->GetOutputPort());
+  mWidget.setLeftAxisMode(vtkScalarsToColorsHistogramChart::MAXIMUM);
+  mWidget.updateHistogram(true);
   mWidget.show();
 
   /// Add presets to the widget selector

+ 18 - 4
Libs/Visualization/VTK/Widgets/ctkVTKDiscretizableColorTransferWidget.cpp

@@ -387,6 +387,22 @@ const
 }
 
 // ----------------------------------------------------------------------------
+void ctkVTKDiscretizableColorTransferWidget::setLeftAxisMode(int mode)
+{
+  Q_D(ctkVTKDiscretizableColorTransferWidget);
+
+  d->scalarsToColorsContextItem->SetLeftAxisMode(mode);
+}
+
+// ----------------------------------------------------------------------------
+int ctkVTKDiscretizableColorTransferWidget::leftAxisMode()
+{
+  Q_D(ctkVTKDiscretizableColorTransferWidget);
+
+  return d->scalarsToColorsContextItem->GetLeftAxisMode();
+}
+
+// ----------------------------------------------------------------------------
 void ctkVTKDiscretizableColorTransferWidget::setHistogramConnection(
   vtkAlgorithmOutput* input)
 {
@@ -620,16 +636,14 @@ void ctkVTKDiscretizableColorTransferWidget::updateHistogram()
     d->histogramFilter->Update();
 
     vtkImageData* histogram = d->histogramFilter->GetOutput();
-    int* output = static_cast<int*>(histogram->GetScalarPointer());
+    vtkIdType* output = static_cast<vtkIdType*>(histogram->GetScalarPointer());
 
     // set min and max of the slider widget
     vtkDataObject* input = d->histogramFilter->GetInputAlgorithm()->GetOutputDataObject(0);
     vtkImageData* inputImage = vtkImageData::SafeDownCast(input);
-
     d->rangeSlider->setCustomSpinBoxesLimits(inputImage->GetScalarTypeMin(),
                                              inputImage->GetScalarTypeMax());
 
-
 #ifdef DEBUG_RANGE
     qDebug() << "DEBUG_RANGE histo input range = " << origin
              << " " << origin + (extent + 1) * spacing;
@@ -641,7 +655,7 @@ void ctkVTKDiscretizableColorTransferWidget::updateHistogram()
     deb << "DEBUG_RANGE histo = ";
     for(vtkIdType i = 0; i < dims[0]; ++i)
     {
-        deb << *(static_cast<int*>(histogram->GetScalarPointer(i, 0, 0))) << " ";
+        deb << *(static_cast<vtkIdType*>(histogram->GetScalarPointer(i, 0, 0))) << " ";
     }
 #endif
 

+ 6 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDiscretizableColorTransferWidget.h

@@ -70,6 +70,12 @@ public:
   void copyColorTransferFunction(vtkScalarsToColors* ctf, bool useCtfRange = false);
   vtkDiscretizableColorTransferFunction* discretizableColorTransferFunction() const;
 
+  /// Set/Get the left axis mode.
+  /// This controls the axis range computation.
+  /// \see vtkScalarsToColorsHistogramChart::SetLeftAxisMode
+  void setLeftAxisMode(int mode);
+  int leftAxisMode();
+
   void setHistogramConnection(vtkAlgorithmOutput* input);
   void updateHistogram(bool updateDataRange);
 

+ 3 - 3
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsComboBox.cpp

@@ -85,6 +85,7 @@ ctkVTKScalarsToColorsComboBox::ctkVTKScalarsToColorsComboBox(QWidget* _parent)
 // --------------------------------------------------------------------------
 ctkVTKScalarsToColorsComboBox::~ctkVTKScalarsToColorsComboBox()
 {
+  this->clear();
 }
 
 // --------------------------------------------------------------------------
@@ -161,12 +162,11 @@ void ctkVTKScalarsToColorsComboBox::onCurrentIndexChanged(int index)
 
 // --------------------------------------------------------------------------
 void ctkVTKScalarsToColorsComboBox::onRowsAboutToBeRemoved(
-  const QModelIndex& parent, int first, int last)
+  const QModelIndex&, int first, int last)
 {
   for (int i = first; i <= last; ++i)
   {
-    vtkScalarsToColors* scFunction = reinterpret_cast<vtkScalarsToColors*>(
-      model()->data(model()->index(i, 0, parent)).value<void*>());
+    vtkScalarsToColors* scFunction = this->getScalarsToColors(i);
     if (scFunction != CTK_NULLPTR)
     {
       scFunction->Delete();

+ 2 - 19
Libs/Widgets/ctkRangeWidget.cpp

@@ -48,7 +48,6 @@ public:
   bool equal(double v1, double v2)const;
   void relayout();
   bool useCustomSpinBoxesLimits()const;
-  double clamp(double v, double min, double max);
 
   bool          Tracking;
   bool          Changing;
@@ -224,20 +223,6 @@ bool ctkRangeWidgetPrivate::useCustomSpinBoxesLimits()const
 }
 
 // --------------------------------------------------------------------------
-double ctkRangeWidgetPrivate::clamp(double v, double min, double max)
-{
-  if (v < min)
-  {
-    v = min;
-  }
-  if (v > max)
-  {
-    v = max;
-  }
-  return v;
-}
-
-// --------------------------------------------------------------------------
 ctkRangeWidget::ctkRangeWidget(QWidget* _parent) : Superclass(_parent)
   , d_ptr(new ctkRangeWidgetPrivate(*this))
 {
@@ -356,10 +341,8 @@ void ctkRangeWidget::setRange(double min, double max)
 
   if (d->useCustomSpinBoxesLimits())
     {
-    min = d->clamp(min, d->CustomSpinBoxesLimitsMin,
-                        d->CustomSpinBoxesLimitsMax);
-    max = d->clamp(max, d->CustomSpinBoxesLimitsMin,
-                        d->CustomSpinBoxesLimitsMax);
+    min = qBound(d->CustomSpinBoxesLimitsMin, min, d->CustomSpinBoxesLimitsMax);
+    max = qBound(d->CustomSpinBoxesLimitsMin, max, d->CustomSpinBoxesLimitsMax);
     }
 
   double oldMin = d->MinimumSpinBox->minimum();