Browse Source

Merge pull request #757 from LucasGandel/discretizable-transfer-widget-range

Introduce limit range to match both data and LUT ranges
Julien Finet 7 years ago
parent
commit
b6a9eb20d3

+ 28 - 18
Libs/Visualization/VTK/Core/vtkDiscretizableColorTransferChart.cpp

@@ -113,10 +113,9 @@ vtkDiscretizableColorTransferChart::vtkDiscretizableColorTransferChart()
   this->MinMarker = vtkSmartPointer<vtkHistogramMarker>::New();
   this->MaxMarker = vtkSmartPointer<vtkHistogramMarker>::New();
 
-  this->ForceAxesToBoundsOn();
   this->SetAutoAxes(false);
-  this->SetLayoutStrategy(vtkChart::FILL_SCENE);
   this->SetRenderEmpty(true);
+  this->SetLayoutStrategy(vtkChart::FILL_RECT);
   this->ZoomWithMouseWheelOff();
 
   for (int i = 0; i < 4; ++i)
@@ -124,14 +123,24 @@ vtkDiscretizableColorTransferChart::vtkDiscretizableColorTransferChart()
     this->GetAxis(i)->SetVisible(true);
     this->GetAxis(i)->SetNumberOfTicks(0);
     this->GetAxis(i)->SetLabelsVisible(false);
-    this->GetAxis(i)->SetMargins(0, 0);
     this->GetAxis(i)->SetTitle("");
   }
+  this->GetAxis(vtkAxis::LEFT)->SetMargins(20, 0);
+  this->GetAxis(vtkAxis::RIGHT)->SetMargins(20, 0);
+
+  this->GetAxis(vtkAxis::BOTTOM)->SetBehavior(vtkAxis::FIXED);
+
+  ///Disable actions
+  this->SetActionToButton(ZOOM, -1);/// We don't want to zoom
+  this->SetActionToButton(PAN, -1);/// Axes are not forced to bounds, disable panning
 
   this->CompositeHiddenItem = CTK_NULLPTR;
   this->ControlPoints = CTK_NULLPTR;
 
   this->rangeMoving = RangeMoving_NONE;
+
+  this->DataRange[0] = VTK_DOUBLE_MAX;
+  this->DataRange[1] = VTK_DOUBLE_MIN;
 }
 
 // ----------------------------------------------------------------------------
@@ -214,9 +223,6 @@ void vtkDiscretizableColorTransferChart::SetColorTransferFunction(
 
   this->AddPlot(this->CompositeHiddenItem);
   this->AddPlot(this->ControlPoints);
-
-  ///Disable zooming
-  this->SetActionToButton(ZOOM, -1);
 }
 
 // ----------------------------------------------------------------------------
@@ -232,12 +238,16 @@ void vtkDiscretizableColorTransferChart::UpdateMarkerPosition(
   this->Transform->InverseTransformPoints(m.GetScenePos().GetData(),
     pos.GetData(), 1);
 
+  double limitRange[2];
+  limitRange[0] = std::min(this->OriginalRange[0], this->DataRange[0]);
+  limitRange[1] = std::max(this->OriginalRange[1], this->DataRange[1]);
+
   if (rangeMoving == RangeMoving_MIN)
   {
     double newValue = static_cast<double>(pos.GetX());
-    if (newValue < this->OriginalRange[0])
+    if (newValue < limitRange[0])
     {
-      this->CurrentRange[0] = this->OriginalRange[0];
+      this->CurrentRange[0] = limitRange[0];
     }
     else if (newValue < this->CurrentRange[1])
     {
@@ -255,9 +265,9 @@ void vtkDiscretizableColorTransferChart::UpdateMarkerPosition(
   else if (rangeMoving == RangeMoving_MAX)
   {
     double newValue = static_cast<double>(pos.GetX());
-    if (newValue > this->OriginalRange[1])
+    if (newValue > limitRange[1])
     {
-      this->CurrentRange[1] = this->OriginalRange[1];
+      this->CurrentRange[1] = limitRange[1];
     }
     else if (newValue > this->CurrentRange[0])
     {
@@ -408,15 +418,19 @@ double* vtkDiscretizableColorTransferChart::GetDataRange()
 void vtkDiscretizableColorTransferChart::SetCurrentRange(
   double min, double max)
 {
+  double limitRange[2];
+  limitRange[0] = std::min(this->OriginalRange[0], this->DataRange[0]);
+  limitRange[1] = std::max(this->OriginalRange[1], this->DataRange[1]);
+
   ///check if min < max;
-  min = vtkMath::ClampValue(min, this->OriginalRange[0], this->OriginalRange[1]);
-  max = vtkMath::ClampValue(max, this->OriginalRange[0], this->OriginalRange[1]);
+  min = vtkMath::ClampValue(min, limitRange[0], limitRange[1]);
+  max = vtkMath::ClampValue(max, limitRange[0], limitRange[1]);
   if (min < max)
   {
     this->CurrentRange[0] = 
-      min < this->OriginalRange[0] ? this->OriginalRange[0] : min;
+      min < limitRange[0] ? limitRange[0] : min;
     this->CurrentRange[1] =
-      max > this->OriginalRange[1] ? this->OriginalRange[1] : max;
+      max > limitRange[1] ? limitRange[1] : max;
     this->MinMarker->SetPosition(this->CurrentRange[0]);
     this->MaxMarker->SetPosition(this->CurrentRange[1]);
   }
@@ -440,10 +454,6 @@ double* vtkDiscretizableColorTransferChart::GetCurrentRange()
 void vtkDiscretizableColorTransferChart::CenterRange(double center)
 {
   double width = this->CurrentRange[1] - this->CurrentRange[0];
-  double minCenter = this->OriginalRange[0] + width / 2.0;
-  double maxCenter = this->OriginalRange[1] - width / 2.0;
-
-  center = vtkMath::ClampValue(center, minCenter, maxCenter);
   double newMin = center - width / 2;
   double newMax = newMin + width;
 

+ 45 - 7
Libs/Visualization/VTK/Core/vtkScalarsToColorsContextItem.cpp

@@ -70,6 +70,9 @@ vtkScalarsToColorsContextItem::vtkScalarsToColorsContextItem()
 
   this->LastSceneSize = vtkVector2i(0, 0);
 
+  this->LimitRange[0] = VTK_DOUBLE_MIN;
+  this->LimitRange[1] = VTK_DOUBLE_MAX;
+
   vtkSmartPointer<vtkBrush> b = vtkSmartPointer<vtkBrush>::New();
   b->SetOpacityF(0);
 
@@ -167,13 +170,7 @@ void vtkScalarsToColorsContextItem::SetDiscretizableColorTransferFunction(
     this->PrivateEventForwarder, &EventForwarder::ForwardEvent);
 
   /// Set the preview chart range to the color transfer function range
-  if (this->ColorTransferFunction == CTK_NULLPTR)
-  {
-    this->PreviewChart->GetAxis(vtkAxis::BOTTOM)->SetRange(0, 0);
-    return;
-  }
-  this->PreviewChart->GetAxis(vtkAxis::BOTTOM)->SetRange(
-    this->ColorTransferFunction->GetRange());
+  this->RecalculateChartsRange();
 }
 
 // ----------------------------------------------------------------------------
@@ -201,6 +198,7 @@ void vtkScalarsToColorsContextItem::SetHistogramTable(vtkTable* table,
 void vtkScalarsToColorsContextItem::SetDataRange(double min, double max)
 {
   this->EditorChart->SetDataRange(min, max);
+  this->RecalculateChartsRange();
 }
 
 // ----------------------------------------------------------------------------
@@ -228,6 +226,38 @@ void vtkScalarsToColorsContextItem::CenterRange(double center)
 }
 
 // ----------------------------------------------------------------------------
+double* vtkScalarsToColorsContextItem::GetLimitRange()
+{
+  return LimitRange;
+}
+
+// ----------------------------------------------------------------------------
+void vtkScalarsToColorsContextItem::RecalculateChartsRange()
+{
+  if (this->GetDiscretizableColorTransferFunction() == nullptr)
+  {
+    return;
+  }
+
+  /// Recalculate limit range
+  double* ctfRange = this->GetDiscretizableColorTransferFunction()->GetRange();
+  this->LimitRange[0] = std::min(ctfRange[0], this->GetDataRange()[0]);
+  this->LimitRange[1] = std::max(ctfRange[1], this->GetDataRange()[1]);
+
+  this->EditorChart->GetAxis(vtkAxis::BOTTOM)->SetUnscaledRange(
+    this->LimitRange);
+  this->EditorChart->RecalculateBounds();
+
+  this->HistogramChart->GetAxis(vtkAxis::BOTTOM)->SetUnscaledRange(
+    this->LimitRange);
+  this->HistogramChart->RecalculateBounds();
+
+  this->PreviewChart->GetAxis(vtkAxis::BOTTOM)->SetUnscaledRange(
+    this->LimitRange);
+  this->PreviewChart->RecalculateBounds();
+}
+
+// ----------------------------------------------------------------------------
 bool vtkScalarsToColorsContextItem::GetCurrentControlPointColor(double rgb[3])
 {
   return this->EditorChart->GetCurrentControlPointColor(rgb);
@@ -279,6 +309,14 @@ bool vtkScalarsToColorsContextItem::Paint(vtkContext2D* painter)
     this->PreviewChart->SetSize(colorTransferFunctionChartSize);
     this->PreviewChart->SetHiddenAxisBorder(0);
     this->PreviewChart->RecalculateBounds();
+
+    vtkRectf editorChartSize(0.0, 0.0, sceneWidth,
+      sceneHeight);
+    this->EditorChart->SetSize(editorChartSize);
+    this->EditorChart->RecalculateBounds();
+
+    this->HistogramChart->SetSize(editorChartSize);
+    this->HistogramChart->RecalculateBounds();
   }
 
   return this->Superclass::Paint(painter);

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

@@ -78,6 +78,12 @@ public:
   /// Center the color tranfer function around \center
   void CenterRange(double center);
 
+  /// Return the range including both the transfer function and data extents
+  double* GetLimitRange();
+
+  /// Update charts range to match data and color transfer function ranges
+  void RecalculateChartsRange();
+
   /// Weight opacity control points by \opacity 
   void SetGlobalOpacity(double opacity);
 
@@ -103,6 +109,9 @@ private:
   /// Cached geometry of the scene
   vtkVector2i LastSceneSize;
 
+  /// Widest possible range for charts
+  double LimitRange[2];
+
   /// Internal event forwarder
   class EventForwarder;
   EventForwarder* PrivateEventForwarder;

+ 8 - 3
Libs/Visualization/VTK/Core/vtkScalarsToColorsHistogramChart.cpp

@@ -32,17 +32,22 @@ vtkStandardNewMacro(vtkScalarsToColorsHistogramChart)
 // ----------------------------------------------------------------------------
 vtkScalarsToColorsHistogramChart::vtkScalarsToColorsHistogramChart()
 {
-  this->ForceAxesToBoundsOn();
-  this->SetLayoutStrategy(vtkChart::FILL_SCENE);
+  this->SetAutoAxes(false);
+  this->SetRenderEmpty(true);
+  this->SetLayoutStrategy(vtkChart::FILL_RECT);
+  this->ZoomWithMouseWheelOff();
 
   for (int i = 0; i < 4; ++i)
   {
     this->GetAxis(i)->SetVisible(true);
     this->GetAxis(i)->SetNumberOfTicks(0);
     this->GetAxis(i)->SetLabelsVisible(false);
-    this->GetAxis(i)->SetMargins(0, 0);
     this->GetAxis(i)->SetTitle("");
   }
+  this->GetAxis(vtkAxis::LEFT)->SetMargins(20, 0);
+  this->GetAxis(vtkAxis::RIGHT)->SetMargins(20, 0);
+
+  this->GetAxis(vtkAxis::BOTTOM)->SetBehavior(vtkAxis::FIXED);
 
   this->SetBarWidthFraction(1.0);
 

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

@@ -27,7 +27,6 @@ limitations under the License.
 #include "ctkVTKScalarsToColorsComboBox.h"
 
 // VTK includes
-#include <QVTKWidget.h>
 #include <vtkDiscretizableColorTransferFunction.h>
 #include <vtkNew.h>
 #include <vtkPiecewiseFunction.h>

+ 33 - 11
Libs/Visualization/VTK/Widgets/ctkVTKDiscretizableColorTransferWidget.cpp

@@ -57,12 +57,12 @@
 #include <vtkDiscretizableColorTransferFunction.h>
 #include <vtkDoubleArray.h>
 #include <vtkEventQtSlotConnect.h>
+#include <vtkGenericOpenGLRenderWindow.h>
 #include <vtkIntArray.h>
 #include <vtkImageAccumulate.h>
 #include <vtkImageData.h>
 #include <vtkPiecewiseFunction.h>
 #include <vtkRenderer.h>
-#include <vtkRenderWindow.h>
 #include <vtkScalarsToColors.h>
 #include <vtkTable.h>
 
@@ -153,12 +153,18 @@ void ctkVTKDiscretizableColorTransferWidgetPrivate::setupUi(QWidget* widget)
     vtkSmartPointer<vtkScalarsToColorsContextItem>::New();
   this->scalarsToColorsContextView = vtkSmartPointer<vtkContextView> ::New();
 
-  this->scalarsToColorsContextView->GetScene()->AddItem(
-    this->scalarsToColorsContextItem.Get());
+#if CTK_USE_QVTKOPENGLWIDGET
+  vtkSmartPointer<vtkGenericOpenGLRenderWindow> renwin =
+    vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
+  this->ScalarsToColorsView->SetRenderWindow(renwin);
+#endif
+
+  this->scalarsToColorsContextView->SetRenderWindow(
+    this->ScalarsToColorsView->GetRenderWindow());
   this->scalarsToColorsContextView->SetInteractor(
     this->ScalarsToColorsView->GetInteractor());
-  this->ScalarsToColorsView->SetRenderWindow(
-    this->scalarsToColorsContextView->GetRenderWindow());
+  this->scalarsToColorsContextView->GetScene()->AddItem(
+    this->scalarsToColorsContextItem.Get());
 
   q->setViewBackgroundColor(QColor(49, 54, 59));
 
@@ -353,14 +359,15 @@ void ctkVTKDiscretizableColorTransferWidget::setColorTransferFunction(
   d->centerRangeButton->setEnabled(true);
   d->invertColorTransferFunctionButton->setEnabled(true);
 
-  double* newRange = d->scalarsToColorsContextItem->
-    GetDiscretizableColorTransferFunction()->GetRange();
-
-  d->rangeSlider->setRange(newRange[0], newRange[1]);
-
   d->previousOpacityValue = 1.0;
   d->opacitySlider->setValue(d->previousOpacityValue);
 
+  double* crng = d->scalarsToColorsContextItem->
+    GetDiscretizableColorTransferFunction()->GetRange();
+  double* limitRange = d->scalarsToColorsContextItem->GetLimitRange();
+  d->rangeSlider->setRange(limitRange[0], limitRange[1]);
+  d->rangeSlider->setValues(crng[0], crng[1]);
+
   ctf->AddObserver(
     vtkCommand::ModifiedEvent, d->colorTransferFunctionModified);
   d->colorTransferFunctionModified->Execute(ctf, vtkCommand::ModifiedEvent,
@@ -376,6 +383,15 @@ ctkVTKDiscretizableColorTransferWidget::colorTransferFunction() const
 }
 
 // ----------------------------------------------------------------------------
+vtkDiscretizableColorTransferFunction*
+ctkVTKDiscretizableColorTransferWidget::discretizableColorTransferFunction()
+const
+{
+  Q_D(const ctkVTKDiscretizableColorTransferWidget);
+  return d->scalarsToColorsContextItem->GetDiscretizableColorTransferFunction();
+}
+
+// ----------------------------------------------------------------------------
 void ctkVTKDiscretizableColorTransferWidget::setHistogram(
   vtkImageAccumulate* histogram)
 {
@@ -416,7 +432,13 @@ void ctkVTKDiscretizableColorTransferWidget::setHistogram(
 
   d->scalarsToColorsContextItem->SetDataRange(d->dataRange[0], d->dataRange[1]);
 
-  d->ScalarsToColorsView->GetInteractor()->Render();
+  if (this->discretizableColorTransferFunction() == nullptr)
+  {
+    return;
+  }
+
+  double* limitRange = d->scalarsToColorsContextItem->GetLimitRange();
+  d->rangeSlider->setRange(limitRange[0], limitRange[1]);
 }
 
 // ----------------------------------------------------------------------------

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

@@ -28,7 +28,7 @@ class ctkVTKScalarsToColorsComboBox;
 
 // VTK includes
 #include <vtkSmartPointer.h>
-class QVTKWidget;
+class vtkDiscretizableColorTransferFunction;
 class vtkImageAccumulate;
 class vtkPiecewiseFunction;
 class vtkScalarsToColors;
@@ -53,6 +53,7 @@ public:
 
   void setColorTransferFunction(vtkScalarsToColors* ctf);
   vtkScalarsToColors* colorTransferFunction() const;
+  vtkDiscretizableColorTransferFunction* discretizableColorTransferFunction() const;
 
   void setHistogram(vtkImageAccumulate* hist);