1 /*=========================================================================
2 
3   Library:   CTK
4 
5   Copyright (c) Kitware Inc.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11       http://www.apache.org/licenses/LICENSE-2.0.txt
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 =========================================================================*/
20 
21 // Qt includes
22 #include <QDebug>
23 #include <QToolButton>
24 
25 // CTK includes
26 #include "ctkLogger.h"
27 #include "ctkVTKScalarsToColorsView.h"
28 #include "ctkVTKVolumePropertyWidget.h"
29 #include "ctkUtils.h"
30 #include "ui_ctkVTKVolumePropertyWidget.h"
31 
32 // VTK includes
33 #include <vtkColorTransferControlPointsItem.h>
34 #include <vtkColorTransferFunction.h>
35 #include <vtkColorTransferFunctionItem.h>
36 #include <vtkCompositeControlPointsItem.h>
37 #include <vtkCompositeTransferFunctionItem.h>
38 #include <vtkContextScene.h>
39 #include <vtkLookupTable.h>
40 #include <vtkLookupTableItem.h>
41 #include <vtkPiecewiseControlPointsItem.h>
42 #include <vtkPiecewiseFunction.h>
43 #include <vtkPiecewiseFunctionItem.h>
44 #include <vtkVolumeProperty.h>
45 
46 //----------------------------------------------------------------------------
47 static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKVolumePropertyWidget");
48 //----------------------------------------------------------------------------
49 
50 class ctkVTKVolumePropertyWidgetPrivate:
51   public Ui_ctkVTKVolumePropertyWidget
52 {
53    Q_DECLARE_PUBLIC(ctkVTKVolumePropertyWidget);
54 protected:
55   ctkVTKVolumePropertyWidget* const q_ptr;
56 public:
57   ctkVTKVolumePropertyWidgetPrivate(ctkVTKVolumePropertyWidget& object);
58   void setupUi(QWidget* widget);
59   void computeRange(double* range);
60   void updateThresholdSlider(vtkPiecewiseFunction* opacityFunction);
61   void setThreshold(double min, double max, double opacity);
62 
63   vtkVolumeProperty* VolumeProperty;
64   int                CurrentComponent;
65   QToolButton*       ShowOpacityThresholdWidgetButton;
66 };
67 
68 // ----------------------------------------------------------------------------
69 // ctkVTKVolumePropertyWidgetPrivate methods
70 
71 // ----------------------------------------------------------------------------
ctkVTKVolumePropertyWidgetPrivate(ctkVTKVolumePropertyWidget & object)72 ctkVTKVolumePropertyWidgetPrivate::ctkVTKVolumePropertyWidgetPrivate(
73   ctkVTKVolumePropertyWidget& object)
74   : q_ptr(&object)
75 {
76   this->VolumeProperty = 0;
77   this->CurrentComponent = 0;
78 }
79 
80 // ----------------------------------------------------------------------------
setupUi(QWidget * widget)81 void ctkVTKVolumePropertyWidgetPrivate::setupUi(QWidget* widget)
82 {
83   Q_Q(ctkVTKVolumePropertyWidget);
84   Q_ASSERT(q == widget);
85   this->Ui_ctkVTKVolumePropertyWidget::setupUi(widget);
86 
87   double validBounds[4] = {VTK_DOUBLE_MIN, VTK_DOUBLE_MAX, 0., 1.};
88   this->ScalarOpacityWidget->view()->setValidBounds(validBounds);
89   this->ScalarColorWidget->view()->setValidBounds(validBounds);
90   this->GradientWidget->view()->setValidBounds(validBounds);
91 
92   QObject::connect(this->ScalarOpacityWidget->view(), SIGNAL(extentChanged()),
93                    q, SIGNAL(chartsExtentChanged()));
94 
95   this->ScalarOpacityWidget->view()->addCompositeFunction(0, 0, true, true);
96   vtkCompositeControlPointsItem* composite =
97   vtkCompositeControlPointsItem::SafeDownCast(
98     this->ScalarOpacityWidget->view()->opacityFunctionPlots()[1]);
99   composite->SetColorFill(true);
100   composite->SetPointsFunction(vtkCompositeControlPointsItem::OpacityPointsFunction);
101   this->ScalarColorWidget->view()->addColorTransferFunction(0);
102   this->GradientWidget->view()->addPiecewiseFunction(0);
103 
104   this->ShowOpacityThresholdWidgetButton = new QToolButton;
105   this->ShowOpacityThresholdWidgetButton->setIcon(
106     QIcon(":Icons/threshold.png"));
107   this->ShowOpacityThresholdWidgetButton->setCheckable(true);
108   this->ShowOpacityThresholdWidgetButton->setAutoRaise(true);
109   QObject::connect(this->ShowOpacityThresholdWidgetButton,
110                    SIGNAL(toggled(bool)),
111                    q, SLOT(onThresholdOpacityToggled(bool)));
112   QObject::connect(this->ShowOpacityThresholdWidgetButton,
113                    SIGNAL(toggled(bool)),
114                    q, SIGNAL(thresholdEnabledChanged(bool)));
115   this->ScalarOpacityWidget->addExtraWidget(
116     this->ShowOpacityThresholdWidgetButton);
117   this->ScalarOpacityThresholdWidget->setVisible(false);
118 
119   QObject::connect(this->ScalarOpacityWidget, SIGNAL(axesModified()),
120                    q, SLOT(onAxesModified()), Qt::QueuedConnection);
121   QObject::connect(this->ScalarColorWidget, SIGNAL(axesModified()),
122                    q, SLOT(onAxesModified()), Qt::QueuedConnection);
123   QObject::connect(this->GradientWidget, SIGNAL(axesModified()),
124                    q, SLOT(onAxesModified()), Qt::QueuedConnection);
125 
126   this->GradientGroupBox->setCollapsed(true);
127   this->AdvancedGroupBox->setCollapsed(true);
128 
129   QObject::connect(this->InterpolationComboBox, SIGNAL(currentIndexChanged(int)),
130                    q, SLOT(setInterpolationMode(int)));
131   QObject::connect(this->ShadeCheckBox, SIGNAL(toggled(bool)),
132                    q, SLOT(setShade(bool)));
133   QObject::connect(this->MaterialPropertyWidget, SIGNAL(ambientChanged(double)),
134                    q, SLOT(setAmbient(double)));
135   QObject::connect(this->MaterialPropertyWidget, SIGNAL(diffuseChanged(double)),
136                    q, SLOT(setDiffuse(double)));
137   QObject::connect(this->MaterialPropertyWidget, SIGNAL(specularChanged(double)),
138                    q, SLOT(setSpecular(double)));
139   QObject::connect(this->MaterialPropertyWidget, SIGNAL(specularPowerChanged(double)),
140                    q, SLOT(setSpecularPower(double)));
141 }
142 
143 // ----------------------------------------------------------------------------
computeRange(double * range)144 void ctkVTKVolumePropertyWidgetPrivate::computeRange(double* range)
145 {
146   if (!this->VolumeProperty)
147     {
148     range[0] = 0.;
149     range[1] = 1.;
150     return;
151     }
152   range[0] = VTK_DOUBLE_MAX;
153   range[1] = VTK_DOUBLE_MIN;
154 
155   Q_ASSERT(this->VolumeProperty->GetRGBTransferFunction(this->CurrentComponent));
156   Q_ASSERT(this->VolumeProperty->GetScalarOpacity(this->CurrentComponent));
157   Q_ASSERT(this->VolumeProperty->GetGradientOpacity(this->CurrentComponent));
158 
159   double colorRange[2] = {0., 1.};
160   this->VolumeProperty->GetRGBTransferFunction(this->CurrentComponent)->GetRange(colorRange);
161   range[0] = qMin(range[0], colorRange[0]);
162   range[1] = qMax(range[1], colorRange[1]);
163 
164   double opacityRange[2] = {0., 1.};
165   this->VolumeProperty->GetScalarOpacity(this->CurrentComponent)->GetRange(opacityRange);
166   range[0] = qMin(range[0], opacityRange[0]);
167   range[1] = qMax(range[1], opacityRange[1]);
168 
169   double gradientRange[2] = {0., 1.};
170   this->VolumeProperty->GetGradientOpacity(this->CurrentComponent)->GetRange(gradientRange);
171   range[0] = qMin(range[0], gradientRange[0]);
172   range[1] = qMax(range[1], gradientRange[1]);
173 }
174 
175 // ----------------------------------------------------------------------------
176 // ctkVTKVolumePropertyWidget methods
177 
178 // ----------------------------------------------------------------------------
ctkVTKVolumePropertyWidget(QWidget * parentWidget)179 ctkVTKVolumePropertyWidget::ctkVTKVolumePropertyWidget(QWidget* parentWidget)
180   :QWidget(parentWidget)
181    , d_ptr(new ctkVTKVolumePropertyWidgetPrivate(*this))
182 {
183   Q_D(ctkVTKVolumePropertyWidget);
184   d->setupUi(this);
185 }
186 
187 // ----------------------------------------------------------------------------
~ctkVTKVolumePropertyWidget()188 ctkVTKVolumePropertyWidget::~ctkVTKVolumePropertyWidget()
189 {
190 }
191 
192 // ----------------------------------------------------------------------------
volumeProperty() const193 vtkVolumeProperty* ctkVTKVolumePropertyWidget::volumeProperty()const
194 {
195   Q_D(const ctkVTKVolumePropertyWidget);
196   return d->VolumeProperty;
197 }
198 
199 // ----------------------------------------------------------------------------
200 void ctkVTKVolumePropertyWidget
setVolumeProperty(vtkVolumeProperty * newVolumeProperty)201 ::setVolumeProperty(vtkVolumeProperty* newVolumeProperty)
202 {
203   Q_D(ctkVTKVolumePropertyWidget);
204   if (d->VolumeProperty == newVolumeProperty)
205     {
206     return;
207     }
208   this->qvtkReconnect(d->VolumeProperty, newVolumeProperty,
209                       vtkCommand::ModifiedEvent,
210                       this, SLOT(updateFromVolumeProperty()));
211   d->VolumeProperty = newVolumeProperty;
212 
213   this->updateFromVolumeProperty();
214 }
215 
216 // ----------------------------------------------------------------------------
updateFromVolumeProperty()217 void ctkVTKVolumePropertyWidget::updateFromVolumeProperty()
218 {
219   Q_D(ctkVTKVolumePropertyWidget);
220   vtkColorTransferFunction* colorTransferFunction = 0;
221   vtkPiecewiseFunction* opacityFunction = 0;
222   vtkPiecewiseFunction* gradientFunction = 0;
223   if (d->VolumeProperty)
224     {
225     colorTransferFunction =
226       d->VolumeProperty->GetRGBTransferFunction()->GetSize() ?
227       d->VolumeProperty->GetRGBTransferFunction() : 0;
228     opacityFunction =
229       d->VolumeProperty->GetScalarOpacity()->GetSize() ?
230       d->VolumeProperty->GetScalarOpacity() : 0;
231     gradientFunction =
232       d->VolumeProperty->GetGradientOpacity()->GetSize() ?
233       d->VolumeProperty->GetGradientOpacity() : 0;
234     }
235 
236   d->ScalarOpacityThresholdWidget->setPiecewiseFunction(
237     this->isThresholdEnabled() ? opacityFunction : 0);
238 
239   this->qvtkDisconnect(0, vtkCommand::EndInteractionEvent,
240                        this, SLOT(updateRange()));
241   this->qvtkConnect(opacityFunction, vtkCommand::EndInteractionEvent,
242                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
243   this->qvtkConnect(opacityFunction, vtkCommand::EndEvent,
244                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
245   this->qvtkConnect(colorTransferFunction, vtkCommand::EndInteractionEvent,
246                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
247   this->qvtkConnect(colorTransferFunction, vtkCommand::EndEvent,
248                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
249   this->qvtkConnect(gradientFunction, vtkCommand::EndInteractionEvent,
250                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
251   this->qvtkConnect(gradientFunction, vtkCommand::EndEvent,
252                     this, SLOT(updateRange()), 0., Qt::QueuedConnection);
253 
254   d->ScalarOpacityWidget->view()->setOpacityFunctionToPlots(opacityFunction);
255   d->ScalarOpacityWidget->view()->setColorTransferFunctionToPlots(colorTransferFunction);
256   d->ScalarColorWidget->view()->setColorTransferFunctionToPlots(colorTransferFunction);
257   d->GradientWidget->view()->setPiecewiseFunctionToPlots(gradientFunction);
258 
259   if (d->VolumeProperty)
260     {
261     d->InterpolationComboBox->setCurrentIndex(
262       d->VolumeProperty->GetInterpolationType() == VTK_NEAREST_INTERPOLATION ? 0 : 1);
263     d->ShadeCheckBox->setChecked(d->VolumeProperty->GetShade(d->CurrentComponent));
264     d->MaterialPropertyWidget->setAmbient(d->VolumeProperty->GetAmbient(d->CurrentComponent));
265     d->MaterialPropertyWidget->setDiffuse(d->VolumeProperty->GetDiffuse(d->CurrentComponent));
266     d->MaterialPropertyWidget->setSpecular(d->VolumeProperty->GetSpecular(d->CurrentComponent));
267     d->MaterialPropertyWidget->setSpecularPower(d->VolumeProperty->GetSpecularPower(d->CurrentComponent));
268     }
269   this->updateRange();
270 }
271 
272 // ----------------------------------------------------------------------------
updateRange()273 void ctkVTKVolumePropertyWidget::updateRange()
274 {
275   Q_D(ctkVTKVolumePropertyWidget);
276 
277   double range[2] = {0.0};
278   d->computeRange(range);
279   d->ScalarOpacityThresholdWidget->setRange(range[0], range[1]);
280 
281   // Elements: {leftMin, leftMax, bottomMin, bottomMax, rightMin, rightMax, topMin, topMax}
282   // (probably according to vtkAxis::Location)
283   double chartBounds[8] = {0.0};
284   d->ScalarOpacityWidget->view()->chartBounds(chartBounds);
285   chartBounds[2] = range[0];
286   chartBounds[3] = range[1];
287   d->ScalarOpacityWidget->view()->setChartUserBounds(chartBounds);
288   d->ScalarOpacityWidget->view()->update();
289 
290   d->ScalarColorWidget->view()->chartBounds(chartBounds);
291   chartBounds[2] = range[0];
292   chartBounds[3] = range[1];
293   d->ScalarColorWidget->view()->setChartUserBounds(chartBounds);
294   d->ScalarColorWidget->view()->update();
295 
296   d->GradientWidget->view()->chartBounds(chartBounds);
297   chartBounds[2] = range[0];
298   chartBounds[3] = range[1];
299   d->GradientWidget->view()->setChartUserBounds(chartBounds);
300   d->GradientWidget->view()->update();
301 }
302 
303 // ----------------------------------------------------------------------------
chartsBounds(double bounds[4]) const304 void ctkVTKVolumePropertyWidget::chartsBounds(double bounds[4])const
305 {
306   Q_D(const ctkVTKVolumePropertyWidget);
307 
308   double chartBounds[8] = {0.0};
309   d->ScalarOpacityWidget->view()->chartBounds(chartBounds);
310   memcpy(bounds, chartBounds, 4*sizeof(double));
311 
312   d->ScalarColorWidget->view()->chartBounds(chartBounds);
313   bounds[0] = qMin(bounds[0], chartBounds[0]);
314   bounds[1] = qMax(bounds[1], chartBounds[1]);
315   bounds[2] = qMin(bounds[2], chartBounds[2]);
316   bounds[3] = qMax(bounds[3], chartBounds[3]);
317 
318   d->GradientWidget->view()->chartBounds(chartBounds);
319   bounds[0] = qMin(bounds[0], chartBounds[0]);
320   bounds[1] = qMax(bounds[1], chartBounds[1]);
321   bounds[2] = qMin(bounds[2], chartBounds[2]);
322   bounds[3] = qMax(bounds[3], chartBounds[3]);
323 }
324 
325 // ----------------------------------------------------------------------------
chartsBounds() const326 QList<double> ctkVTKVolumePropertyWidget::chartsBounds()const
327 {
328   double boundsArray[4] = {0.0};
329   this->chartsBounds(boundsArray);
330 
331   QList<double> bounds;
332   bounds << boundsArray[0] << boundsArray[1] << boundsArray[2] << boundsArray[3];
333   return bounds;
334 }
335 
336 // ----------------------------------------------------------------------------
setChartsExtent(double extent[2])337 void ctkVTKVolumePropertyWidget::setChartsExtent(double extent[2])
338 {
339   this->setChartsExtent(extent[0], extent[1]);
340 }
341 
342 // ----------------------------------------------------------------------------
setChartsExtent(double min,double max)343 void ctkVTKVolumePropertyWidget::setChartsExtent(double min, double max)
344 {
345   Q_D(ctkVTKVolumePropertyWidget);
346 
347   double chartExtent[8] = {0.0};
348   d->ScalarOpacityWidget->view()->chartExtent(chartExtent);
349   chartExtent[0] = min;
350   chartExtent[1] = max;
351   d->ScalarOpacityWidget->view()->setChartUserExtent(chartExtent);
352   d->ScalarOpacityWidget->view()->update();
353 
354   d->ScalarColorWidget->view()->chartExtent(chartExtent);
355   chartExtent[0] = min;
356   chartExtent[1] = max;
357   d->ScalarColorWidget->view()->setChartUserExtent(chartExtent);
358   d->ScalarColorWidget->view()->update();
359 
360   d->GradientWidget->view()->chartExtent(chartExtent);
361   chartExtent[0] = min;
362   chartExtent[1] = max;
363   d->GradientWidget->view()->setChartUserExtent(chartExtent);
364   d->GradientWidget->view()->update();
365 }
366 
367 // ----------------------------------------------------------------------------
chartsExtent(double extent[4]) const368 void ctkVTKVolumePropertyWidget::chartsExtent(double extent[4])const
369 {
370   Q_D(const ctkVTKVolumePropertyWidget);
371 
372   double chartExtent[8] = {0.0};
373   d->ScalarOpacityWidget->view()->chartExtent(chartExtent);
374   memcpy(extent, chartExtent, 4*sizeof(double));
375 
376   d->ScalarColorWidget->view()->chartExtent(chartExtent);
377   extent[0] = qMin(extent[0], chartExtent[0]);
378   extent[1] = qMax(extent[1], chartExtent[1]);
379   extent[2] = qMin(extent[2], chartExtent[2]);
380   extent[3] = qMax(extent[3], chartExtent[3]);
381 
382   d->GradientWidget->view()->chartExtent(chartExtent);
383   extent[0] = qMin(extent[0], chartExtent[0]);
384   extent[1] = qMax(extent[1], chartExtent[1]);
385   extent[2] = qMin(extent[2], chartExtent[2]);
386   extent[3] = qMax(extent[3], chartExtent[3]);
387 }
388 
389 // ----------------------------------------------------------------------------
chartsExtent() const390 QList<double> ctkVTKVolumePropertyWidget::chartsExtent()const
391 {
392   double extentArray[4] = {0.0};
393   this->chartsExtent(extentArray);
394 
395   QList<double> extent;
396   extent << extentArray[0] << extentArray[1] << extentArray[2] << extentArray[3];
397   return extent;
398 }
399 
400 // ----------------------------------------------------------------------------
setInterpolationMode(int mode)401 void ctkVTKVolumePropertyWidget::setInterpolationMode(int mode)
402 {
403   Q_D(ctkVTKVolumePropertyWidget);
404   if (!d->VolumeProperty)
405     {
406     return;
407     }
408   d->VolumeProperty->SetInterpolationType(mode);
409 }
410 
411 // ----------------------------------------------------------------------------
setShade(bool enable)412 void ctkVTKVolumePropertyWidget::setShade(bool enable)
413 {
414   Q_D(ctkVTKVolumePropertyWidget);
415   if (!d->VolumeProperty)
416     {
417     return;
418     }
419   d->VolumeProperty->SetShade(d->CurrentComponent, enable);
420 }
421 
422 // ----------------------------------------------------------------------------
setAmbient(double value)423 void ctkVTKVolumePropertyWidget::setAmbient(double value)
424 {
425   Q_D(ctkVTKVolumePropertyWidget);
426   if (!d->VolumeProperty)
427     {
428     return;
429     }
430   d->VolumeProperty->SetAmbient(d->CurrentComponent, value);
431 }
432 
433 // ----------------------------------------------------------------------------
setDiffuse(double value)434 void ctkVTKVolumePropertyWidget::setDiffuse(double value)
435 {
436   Q_D(ctkVTKVolumePropertyWidget);
437   if (!d->VolumeProperty)
438     {
439     return;
440     }
441   d->VolumeProperty->SetDiffuse(d->CurrentComponent, value);
442 }
443 
444 // ----------------------------------------------------------------------------
setSpecular(double value)445 void ctkVTKVolumePropertyWidget::setSpecular(double value)
446 {
447   Q_D(ctkVTKVolumePropertyWidget);
448   if (!d->VolumeProperty)
449     {
450     return;
451     }
452   d->VolumeProperty->SetSpecular(d->CurrentComponent, value);
453 }
454 
455 // ----------------------------------------------------------------------------
setSpecularPower(double value)456 void ctkVTKVolumePropertyWidget::setSpecularPower(double value)
457 {
458   Q_D(ctkVTKVolumePropertyWidget);
459   if (!d->VolumeProperty)
460     {
461     return;
462     }
463   d->VolumeProperty->SetSpecularPower(d->CurrentComponent, value);
464 }
465 
466 // ----------------------------------------------------------------------------
isThresholdEnabled() const467 bool ctkVTKVolumePropertyWidget::isThresholdEnabled()const
468 {
469   Q_D(const ctkVTKVolumePropertyWidget);
470   return d->ScalarOpacityThresholdWidget->isVisibleTo(
471     const_cast<ctkVTKVolumePropertyWidget*>(this));
472 }
473 
474 // ----------------------------------------------------------------------------
setThresholdEnabled(bool enable)475 void ctkVTKVolumePropertyWidget::setThresholdEnabled(bool enable)
476 {
477   Q_D(ctkVTKVolumePropertyWidget);
478   d->ShowOpacityThresholdWidgetButton->setChecked(enable);
479 }
480 
481 // ----------------------------------------------------------------------------
onThresholdOpacityToggled(bool enable)482 void ctkVTKVolumePropertyWidget::onThresholdOpacityToggled(bool enable)
483 {
484   Q_D(ctkVTKVolumePropertyWidget);
485   d->ScalarOpacityThresholdWidget->setVisible(enable);
486   this->updateFromVolumeProperty();
487 }
488 
489 // ----------------------------------------------------------------------------
isThresholdToggleVisible() const490 bool ctkVTKVolumePropertyWidget::isThresholdToggleVisible()const
491 {
492   Q_D(const ctkVTKVolumePropertyWidget);
493   return d->ShowOpacityThresholdWidgetButton->isVisibleTo(
494     const_cast<ctkVTKVolumePropertyWidget*>(this));
495 }
496 
497 // ----------------------------------------------------------------------------
setThresholdToggleVisible(bool showToggle)498 void ctkVTKVolumePropertyWidget::setThresholdToggleVisible(bool showToggle)
499 {
500   Q_D(ctkVTKVolumePropertyWidget);
501   d->ShowOpacityThresholdWidgetButton->setVisible(showToggle);
502 }
503 
504 // ----------------------------------------------------------------------------
onAxesModified()505 void ctkVTKVolumePropertyWidget::onAxesModified()
506 {
507   Q_D(ctkVTKVolumePropertyWidget);
508   //return;
509   ctkVTKScalarsToColorsWidget* senderWidget =
510     qobject_cast<ctkVTKScalarsToColorsWidget*>(this->sender());
511 
512   double xRange[2] = {0.,0.};
513   senderWidget->xRange(xRange);
514   if (senderWidget != d->ScalarOpacityWidget)
515     {
516     bool wasBlocking = d->ScalarOpacityWidget->blockSignals(true);
517     d->ScalarOpacityWidget->setXRange(xRange[0], xRange[1]);
518     d->ScalarOpacityWidget->blockSignals(wasBlocking);
519     }
520   if (senderWidget != d->ScalarColorWidget)
521     {
522     bool wasBlocking = d->ScalarColorWidget->blockSignals(true);
523     d->ScalarColorWidget->setXRange(xRange[0], xRange[1]);
524     d->ScalarColorWidget->blockSignals(wasBlocking);
525     }
526   if (senderWidget != d->GradientWidget)
527     {
528     bool wasBlocking = d->GradientWidget->blockSignals(true);
529     d->GradientWidget->setXRange(xRange[0], xRange[1]);
530     d->GradientWidget->blockSignals(wasBlocking);
531     }
532 }
533 
534 // ----------------------------------------------------------------------------
moveAllPoints(double xOffset,double yOffset,bool dontMoveFirstAndLast)535 void ctkVTKVolumePropertyWidget::moveAllPoints(double xOffset, double yOffset,
536                                                bool dontMoveFirstAndLast)
537 {
538   Q_D(ctkVTKVolumePropertyWidget);
539   if (d->VolumeProperty)
540     {
541     d->VolumeProperty->InvokeEvent(vtkCommand::StartEvent);
542     }
543   d->ScalarOpacityWidget->view()
544     ->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
545   d->ScalarColorWidget->view()
546     ->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
547   d->GradientWidget->view()
548     ->moveAllPoints(xOffset, yOffset, dontMoveFirstAndLast);
549   if (d->VolumeProperty)
550     {
551     d->VolumeProperty->InvokeEvent(vtkCommand::EndEvent);
552     }
553 }
554 
555 // ----------------------------------------------------------------------------
spreadAllPoints(double factor,bool dontSpreadFirstAndLast)556 void ctkVTKVolumePropertyWidget::spreadAllPoints(double factor,
557                                                  bool dontSpreadFirstAndLast)
558 {
559   Q_D(ctkVTKVolumePropertyWidget);
560   if (d->VolumeProperty)
561     {
562     d->VolumeProperty->InvokeEvent(vtkCommand::StartEvent);
563     }
564   d->ScalarOpacityWidget->view()
565     ->spreadAllPoints(factor, dontSpreadFirstAndLast);
566   d->ScalarColorWidget->view()
567     ->spreadAllPoints(factor, dontSpreadFirstAndLast);
568   d->GradientWidget->view()
569     ->spreadAllPoints(factor, dontSpreadFirstAndLast);
570   if (d->VolumeProperty)
571     {
572     d->VolumeProperty->InvokeEvent(vtkCommand::EndEvent);
573     }
574 }
575