Quellcode durchsuchen

Add options to handle color widget height

Improve the ctkVTKDiscretizableColorTransferWidget:
- Add options to set the histogram chart height
- Fix histogram conversion
- Replace clamp by qBound
Tristan vor 7 Jahren
Ursprung
Commit
0583e928b1

+ 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

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

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

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

@@ -46,6 +46,8 @@ class CTK_VISUALIZATION_VTK_CORE_EXPORT vtkScalarsToColorsContextItem
 public:
   static vtkScalarsToColorsContextItem* New();
 
+  void SetLeftAxisMode(int mode);
+
   /// Copy the color transfer function as a vtkDiscretizableColorTransferFunction
   void CopyColorTransferFunction(vtkScalarsToColors* ctf);
   vtkDiscretizableColorTransferFunction* GetDiscretizableColorTransferFunction();

+ 51 - 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,55 @@ vtkScalarsToColorsHistogramChart::~vtkScalarsToColorsHistogramChart()
 }
 
 // ----------------------------------------------------------------------------
+void vtkScalarsToColorsHistogramChart::SetLeftAxisMode(int mode)
+{
+  this->LeftAxisMode = 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:
+      break;
+  }
+}
+
+// ----------------------------------------------------------------------------
 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();

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

@@ -37,6 +37,15 @@ 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".
+  };
+
+  void SetLeftAxisMode(int mode);
+
   /// Set input for histogram
   virtual void SetHistogramInputData(vtkTable* table, const char* xAxisColumn,
     const char* yAxisColumn);
@@ -52,6 +61,7 @@ public:
 
 protected:
   vtkNew<vtkPlotBar> HistogramPlotBar;
+  int LeftAxisMode;
 
 private:
   vtkScalarsToColorsHistogramChart();

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

@@ -387,6 +387,14 @@ const
 }
 
 // ----------------------------------------------------------------------------
+void ctkVTKDiscretizableColorTransferWidget::setLeftAxisMode(int mode)
+{
+  Q_D(ctkVTKDiscretizableColorTransferWidget);
+
+  d->scalarsToColorsContextItem->SetLeftAxisMode(mode);
+}
+
+// ----------------------------------------------------------------------------
 void ctkVTKDiscretizableColorTransferWidget::setHistogramConnection(
   vtkAlgorithmOutput* input)
 {
@@ -620,16 +628,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 +647,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
 

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

@@ -70,6 +70,8 @@ public:
   void copyColorTransferFunction(vtkScalarsToColors* ctf, bool useCtfRange = false);
   vtkDiscretizableColorTransferFunction* discretizableColorTransferFunction() const;
 
+  void setLeftAxisMode(int mode);
+
   void setHistogramConnection(vtkAlgorithmOutput* input);
   void updateHistogram(bool updateDataRange);
 

+ 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();