Переглянути джерело

Merge branch 'TransferFunctionWidget'

* TransferFunctionWidget:
  Set axes to their bounds when adding scalarstocolors plots
  Add Designer plugin to ctkVTKVolumePropertyWidget
  Control visibility of ctkVTKScalarsToColorsWidget sliders
  Add ctkVTKVolumePropertyWidget to control vtkVolumeProperty
  Add Qt Designer plugin for ctkVTKScalarsToColorsWidget
  Refresh view when axes are modified.
  Add test to ctkVTKScalarsToColorsWidget
  TO AMEND
Julien Finet 14 роки тому
батько
коміт
b9320f6a31
26 змінених файлів з 1813 додано та 123 видалено
  1. 5 1
      Libs/Visualization/VTK/Widgets/CMakeLists.txt
  2. 6 0
      Libs/Visualization/VTK/Widgets/Plugins/CMakeLists.txt
  3. 6 3
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsViewPlugin.cpp
  4. 64 0
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsWidgetPlugin.cpp
  5. 43 0
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsWidgetPlugin.h
  6. 64 0
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKVolumePropertyWidgetPlugin.cpp
  7. 43 0
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKVolumePropertyWidgetPlugin.h
  8. 4 0
      Libs/Visualization/VTK/Widgets/Plugins/ctkVTKWidgetsPlugins.h
  9. 133 18
      Libs/Visualization/VTK/Widgets/Resources/UI/ctkVTKScalarsToColorsWidget.ui
  10. 152 0
      Libs/Visualization/VTK/Widgets/Resources/UI/ctkVTKVolumePropertyWidget.ui
  11. 6 0
      Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt
  12. 3 4
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest1.cpp
  13. 2 4
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest2.cpp
  14. 2 4
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest3.cpp
  15. 2 4
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest1.cpp
  16. 75 0
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest2.cpp
  17. 67 0
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest3.cpp
  18. 78 0
      Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKVolumePropertyWidgetTest1.cpp
  19. 93 40
      Libs/Visualization/VTK/Widgets/ctkVTKChartView.cpp
  20. 13 2
      Libs/Visualization/VTK/Widgets/ctkVTKChartView.h
  21. 332 29
      Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsView.cpp
  22. 59 6
      Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsView.h
  23. 314 5
      Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.cpp
  24. 31 3
      Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.h
  25. 156 0
      Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.cpp
  26. 60 0
      Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.h

+ 5 - 1
Libs/Visualization/VTK/Widgets/CMakeLists.txt

@@ -84,6 +84,8 @@ IF (${CTK_USE_CHARTS})
   SET(KIT_SRCS
       ctkVTKChartView.cpp
       ctkVTKChartView.h
+      ctkVTKVolumePropertyWidget.cpp
+      ctkVTKVolumePropertyWidget.h
       ctkVTKScalarsToColorsView.cpp
       ctkVTKScalarsToColorsView.h
       ctkVTKScalarsToColorsWidget.cpp
@@ -91,11 +93,13 @@ IF (${CTK_USE_CHARTS})
       ${KIT_SRCS})
   SET(KIT_MOC_SRCS 
       ctkVTKChartView.h
+      ctkVTKVolumePropertyWidget.h
       ctkVTKScalarsToColorsView.h
       ctkVTKScalarsToColorsWidget.h
       ${KIT_MOC_SRCS})
   SET(KIT_UI_FORMS
-      Resources/UI/ctkVTKScalarsToColorsWidget.ui 
+      Resources/UI/ctkVTKVolumePropertyWidget.ui
+      Resources/UI/ctkVTKScalarsToColorsWidget.ui
       ${KIT_UI_FORMS})
   SET(VTK_LIBRARIES
       vtkCharts

+ 6 - 0
Libs/Visualization/VTK/Widgets/Plugins/CMakeLists.txt

@@ -46,9 +46,15 @@ IF(CTK_USE_CHARTS)
   SET(PLUGIN_SRCS
       ctkVTKScalarsToColorsViewPlugin.cpp
       ctkVTKScalarsToColorsViewPlugin.h
+      ctkVTKScalarsToColorsWidgetPlugin.cpp
+      ctkVTKScalarsToColorsWidgetPlugin.h
+      ctkVTKVolumePropertyWidgetPlugin.cpp
+      ctkVTKVolumePropertyWidgetPlugin.h
       ${PLUGIN_SRCS})
   SET(PLUGIN_MOC_SRCS
       ctkVTKScalarsToColorsViewPlugin.h
+      ctkVTKScalarsToColorsWidgetPlugin.h
+      ctkVTKVolumePropertyWidgetPlugin.h
       ${PLUGIN_MOC_SRCS})
 ENDIF(CTK_USE_CHARTS)
 

+ 6 - 3
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsViewPlugin.cpp

@@ -23,14 +23,17 @@
 #include "ctkVTKScalarsToColorsViewPlugin.h"
 
 //-----------------------------------------------------------------------------
-ctkVTKScalarsToColorsViewPlugin::ctkVTKScalarsToColorsViewPlugin(QObject *_parent):QObject(_parent)
+ctkVTKScalarsToColorsViewPlugin
+::ctkVTKScalarsToColorsViewPlugin(QObject *parentObject)
+ : QObject(parentObject)
 {
 }
 
 //-----------------------------------------------------------------------------
 QWidget *ctkVTKScalarsToColorsViewPlugin::createWidget(QWidget *parentWidget)
 {
-  ctkVTKScalarsToColorsView* newWidget = new ctkVTKScalarsToColorsView(parentWidget);
+  ctkVTKScalarsToColorsView* newWidget
+    = new ctkVTKScalarsToColorsView(parentWidget);
   return newWidget;
 }
 
@@ -38,7 +41,7 @@ QWidget *ctkVTKScalarsToColorsViewPlugin::createWidget(QWidget *parentWidget)
 QString ctkVTKScalarsToColorsViewPlugin::domXml() const
 {
   return "<widget class=\"ctkVTKScalarsToColorsView\" \
-          name=\"VTKScalarBar\">\n"
+          name=\"ScalarsToColorsView\">\n"
           "</widget>\n";
 }
 

+ 64 - 0
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsWidgetPlugin.cpp

@@ -0,0 +1,64 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkVTKScalarsToColorsWidget.h"
+#include "ctkVTKScalarsToColorsWidgetPlugin.h"
+
+//-----------------------------------------------------------------------------
+ctkVTKScalarsToColorsWidgetPlugin
+::ctkVTKScalarsToColorsWidgetPlugin(QObject *parentObject)
+ : QObject(parentObject)
+{
+}
+
+//-----------------------------------------------------------------------------
+QWidget *ctkVTKScalarsToColorsWidgetPlugin::createWidget(QWidget *parentWidget)
+{
+  ctkVTKScalarsToColorsWidget* newWidget =
+    new ctkVTKScalarsToColorsWidget(parentWidget);
+  return newWidget;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKScalarsToColorsWidgetPlugin::domXml() const
+{
+  return "<widget class=\"ctkVTKScalarsToColorsWidget\" \
+          name=\"ScalarsToColorsWidget\">\n"
+          "</widget>\n";
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKScalarsToColorsWidgetPlugin::includeFile() const
+{
+  return "ctkVTKScalarsToColorsWidget.h";
+}
+
+//-----------------------------------------------------------------------------
+bool ctkVTKScalarsToColorsWidgetPlugin::isContainer() const
+{
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKScalarsToColorsWidgetPlugin::name() const
+{
+  return "ctkVTKScalarsToColorsWidget";
+}

+ 43 - 0
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKScalarsToColorsWidgetPlugin.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKScalarsToColorsWidgetPlugin_h
+#define __ctkVTKScalarsToColorsWidgetPlugin_h
+
+// CTK includes
+#include "ctkVTKWidgetsAbstractPlugin.h"
+
+class CTK_VISUALIZATION_VTK_WIDGETS_PLUGINS_EXPORT ctkVTKScalarsToColorsWidgetPlugin
+  : public QObject
+  , public ctkVTKWidgetsAbstractPlugin
+{
+  Q_OBJECT
+
+public:
+  ctkVTKScalarsToColorsWidgetPlugin(QObject *_parent = 0);
+
+  QWidget *createWidget(QWidget *_parent);
+  QString domXml() const;
+  QString includeFile() const;
+  bool isContainer() const;
+  QString name() const;
+};
+
+#endif

+ 64 - 0
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKVolumePropertyWidgetPlugin.cpp

@@ -0,0 +1,64 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// CTK includes
+#include "ctkVTKVolumePropertyWidget.h"
+#include "ctkVTKVolumePropertyWidgetPlugin.h"
+
+//-----------------------------------------------------------------------------
+ctkVTKVolumePropertyWidgetPlugin
+::ctkVTKVolumePropertyWidgetPlugin(QObject *parentObject)
+ : QObject(parentObject)
+{
+}
+
+//-----------------------------------------------------------------------------
+QWidget *ctkVTKVolumePropertyWidgetPlugin::createWidget(QWidget *parentWidget)
+{
+  ctkVTKVolumePropertyWidget* newWidget =
+    new ctkVTKVolumePropertyWidget(parentWidget);
+  return newWidget;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKVolumePropertyWidgetPlugin::domXml() const
+{
+  return "<widget class=\"ctkVTKVolumePropertyWidget\" \
+          name=\"VolumeProperty\">\n"
+          "</widget>\n";
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKVolumePropertyWidgetPlugin::includeFile() const
+{
+  return "ctkVTKVolumePropertyWidget.h";
+}
+
+//-----------------------------------------------------------------------------
+bool ctkVTKVolumePropertyWidgetPlugin::isContainer() const
+{
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+QString ctkVTKVolumePropertyWidgetPlugin::name() const
+{
+  return "ctkVTKVolumePropertyWidget";
+}

+ 43 - 0
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKVolumePropertyWidgetPlugin.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKVolumePropertyWidgetPlugin_h
+#define __ctkVTKVolumePropertyWidgetPlugin_h
+
+// CTK includes
+#include "ctkVTKWidgetsAbstractPlugin.h"
+
+class CTK_VISUALIZATION_VTK_WIDGETS_PLUGINS_EXPORT ctkVTKVolumePropertyWidgetPlugin :
+  public QObject,
+  public ctkVTKWidgetsAbstractPlugin
+{
+  Q_OBJECT
+
+public:
+  ctkVTKVolumePropertyWidgetPlugin(QObject *parent = 0);
+
+  QWidget *createWidget(QWidget *parent);
+  QString domXml() const;
+  QString includeFile() const;
+  bool isContainer() const;
+  QString name() const;
+};
+
+#endif

+ 4 - 0
Libs/Visualization/VTK/Widgets/Plugins/ctkVTKWidgetsPlugins.h

@@ -32,6 +32,8 @@
 #include "ctkVTKScalarBarWidgetPlugin.h"
 #ifdef CTK_USE_CHARTS
 #include "ctkVTKScalarsToColorsViewPlugin.h"
+#include "ctkVTKScalarsToColorsWidgetPlugin.h"
+#include "ctkVTKVolumePropertyWidgetPlugin.h"
 #endif
 #include "ctkVTKSliceViewPlugin.h"
 #include "ctkVTKSurfaceMaterialPropertyWidgetPlugin.h"
@@ -55,6 +57,8 @@ public:
     plugins << new ctkVTKScalarBarWidgetPlugin;
 #ifdef CTK_USE_CHARTS
     plugins << new ctkVTKScalarsToColorsViewPlugin;
+    plugins << new ctkVTKScalarsToColorsWidgetPlugin;
+    plugins << new ctkVTKVolumePropertyWidgetPlugin;
 #endif
     plugins << new ctkVTKSliceViewPlugin;
     plugins << new ctkVTKSurfaceMaterialPropertyWidgetPlugin;

+ 133 - 18
Libs/Visualization/VTK/Widgets/Resources/UI/ctkVTKScalarsToColorsWidget.ui

@@ -6,14 +6,20 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>429</width>
+    <width>442</width>
     <height>144</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>ScalarsToColorsWidget</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout">
+  <layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <property name="spacing">
+    <number>0</number>
+   </property>
    <item row="0" column="0" colspan="2">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
@@ -30,28 +36,117 @@
       </spacer>
      </item>
      <item>
-      <widget class="QLabel" name="PLabel">
+      <widget class="QLabel" name="PointIdLabel">
+       <property name="toolTip">
+        <string>Point ID</string>
+       </property>
        <property name="text">
-        <string>P:</string>
+        <string>Point:</string>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QDoubleSpinBox" name="PSpinBox">
+      <widget class="QSpinBox" name="PointIdSpinBox">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Point ID</string>
+       </property>
+       <property name="minimum">
+        <number>-1</number>
+       </property>
        <property name="maximum">
-        <double>255.000000000000000</double>
+        <number>-1</number>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QLabel" name="VLabel">
+      <widget class="ctkColorPickerButton" name="ColorPickerButton">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
        <property name="text">
-        <string>V:</string>
+        <string/>
+       </property>
+       <property name="displayColorName">
+        <bool>false</bool>
+       </property>
+       <property name="dialogOptions">
+        <set>ctkColorPickerButton::UseCTKColorDialog</set>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QDoubleSpinBox" name="VSpinBox">
+      <widget class="QLabel" name="OpacityLabel">
+       <property name="toolTip">
+        <string>Opacity of the current point</string>
+       </property>
+       <property name="text">
+        <string>O:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="OpacitySpinBox">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Opacity of the current point</string>
+       </property>
+       <property name="maximum">
+        <double>1.000000000000000</double>
+       </property>
+       <property name="singleStep">
+        <double>0.100000000000000</double>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="MidPointLabel">
+       <property name="toolTip">
+        <string>Position of the midpoint</string>
+       </property>
+       <property name="text">
+        <string>M:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="MidPointSpinBox">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Position of the midpoint</string>
+       </property>
+       <property name="maximum">
+        <double>1.000000000000000</double>
+       </property>
+       <property name="singleStep">
+        <double>0.100000000000000</double>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLabel" name="SharpnessLabel">
+       <property name="toolTip">
+        <string>Sharpness of the midpoint</string>
+       </property>
+       <property name="text">
+        <string>S:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDoubleSpinBox" name="SharpnessSpinBox">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Sharpness of the midpoint</string>
+       </property>
        <property name="maximum">
         <double>1.000000000000000</double>
        </property>
@@ -65,17 +160,32 @@
    <item row="1" column="0">
     <widget class="ctkVTKScalarsToColorsView" name="View"/>
    </item>
-   <item row="1" column="1">
-    <widget class="ctkRangeSlider" name="RangeSlider">
+   <item row="2" column="0">
+    <widget class="ctkDoubleRangeSlider" name="XRangeSlider">
+     <property name="maximum">
+      <double>1.000000000000000</double>
+     </property>
+     <property name="singleStep">
+      <double>0.010000000000000</double>
+     </property>
+     <property name="maximumValue">
+      <double>1.000000000000000</double>
+     </property>
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
-   <item row="2" column="0">
-    <widget class="ctkRangeSlider" name="RangeSlider_2">
+   <item row="1" column="1">
+    <widget class="ctkDoubleRangeSlider" name="YRangeSlider">
+     <property name="maximum">
+      <double>1.000000000000000</double>
+     </property>
+     <property name="singleStep">
+      <double>0.010000000000000</double>
+     </property>
      <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+      <enum>Qt::Vertical</enum>
      </property>
     </widget>
    </item>
@@ -88,9 +198,14 @@
    <header>ctkVTKScalarsToColorsView.h</header>
   </customwidget>
   <customwidget>
-   <class>ctkRangeSlider</class>
-   <extends>QSlider</extends>
-   <header>ctkRangeSlider.h</header>
+   <class>ctkColorPickerButton</class>
+   <extends>QPushButton</extends>
+   <header>ctkColorPickerButton.h</header>
+  </customwidget>
+  <customwidget>
+   <class>ctkDoubleRangeSlider</class>
+   <extends>QWidget</extends>
+   <header>ctkDoubleRangeSlider.h</header>
   </customwidget>
  </customwidgets>
  <resources/>

+ 152 - 0
Libs/Visualization/VTK/Widgets/Resources/UI/ctkVTKVolumePropertyWidget.ui

@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ctkVTKVolumePropertyWidget</class>
+ <widget class="QWidget" name="ctkVTKVolumePropertyWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>435</width>
+    <height>576</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Volume property</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_3">
+   <property name="margin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="ctkCollapsibleGroupBox" name="ScalarOpacityGroupBox">
+     <property name="title">
+      <string>Scalar Opacity Mapping</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="ctkVTKScalarsToColorsWidget" name="ScalarOpacityWidget">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>120</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="ctkCollapsibleGroupBox" name="ScalarColorGroupBox">
+     <property name="title">
+      <string>Scalar Color Mapping</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_4">
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="ctkVTKScalarsToColorsWidget" name="ScalarColorWidget">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>120</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="ctkCollapsibleGroupBox" name="GradientGroupBox">
+     <property name="title">
+      <string>Gradient Opacity</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <property name="margin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="ctkVTKScalarsToColorsWidget" name="GradientWidget">
+        <property name="minimumSize">
+         <size>
+          <width>0</width>
+          <height>120</height>
+         </size>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="ctkCollapsibleGroupBox" name="AdvancedGroupBox">
+     <property name="title">
+      <string>Advanced</string>
+     </property>
+     <layout class="QFormLayout" name="formLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="InterpolationLabel">
+        <property name="text">
+         <string>Interpolation:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="InterpolationComboBox">
+        <item>
+         <property name="text">
+          <string>Nearest Neighbor</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Linear</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="MaterialLabel">
+        <property name="text">
+         <string>Material:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="ctkMaterialPropertyPreviewLabel" name="MaterialPropertyLabel">
+        <property name="gridOpacity">
+         <double>0.000000000000000</double>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ctkVTKScalarsToColorsWidget</class>
+   <extends>QWidget</extends>
+   <header>ctkVTKScalarsToColorsWidget.h</header>
+  </customwidget>
+  <customwidget>
+   <class>ctkCollapsibleGroupBox</class>
+   <extends>QGroupBox</extends>
+   <header>ctkCollapsibleGroupBox.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>ctkMaterialPropertyPreviewLabel</class>
+   <extends>QFrame</extends>
+   <header>ctkMaterialPropertyPreviewLabel.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>

+ 6 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -25,11 +25,14 @@ SET(TEST_SOURCES
 IF(CTK_USE_CHARTS)
   SET(TEST_SOURCES
       ctkVTKChartViewTest1.cpp
+      ctkVTKVolumePropertyWidgetTest1.cpp
       ctkVTKScalarsToColorsViewTest1.cpp
       ctkVTKScalarsToColorsViewTest2.cpp
       ctkVTKScalarsToColorsViewTest3.cpp
       ctkVTKScalarsToColorsViewTest4.cpp
       ctkVTKScalarsToColorsWidgetTest1.cpp
+      ctkVTKScalarsToColorsWidgetTest2.cpp
+      ctkVTKScalarsToColorsWidgetTest3.cpp
       ${TEST_SOURCES})
 ENDIF(CTK_USE_CHARTS)
 
@@ -95,11 +98,14 @@ SIMPLE_TEST( ctkTransferFunctionViewTest4 )
 SIMPLE_TEST( ctkTransferFunctionViewTest5 )
 IF (CTK_USE_CHARTS)
   SIMPLE_TEST( ctkVTKChartViewTest1 )
+  SIMPLE_TEST( ctkVTKVolumePropertyWidgetTest1 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest1 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest2 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest3 )
   SIMPLE_TEST( ctkVTKScalarsToColorsViewTest4 )
   SIMPLE_TEST( ctkVTKScalarsToColorsWidgetTest1 )
+  SIMPLE_TEST( ctkVTKScalarsToColorsWidgetTest2 )
+  SIMPLE_TEST( ctkVTKScalarsToColorsWidgetTest3 )
 ENDIF(CTK_USE_CHARTS)
 SIMPLE_TEST( ctkVTKRenderViewTest1 )
 SIMPLE_TEST( ctkVTKSliceViewTest1 )

+ 3 - 4
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest1.cpp

@@ -47,15 +47,14 @@ int ctkVTKScalarsToColorsViewTest1(int argc, char * argv [] )
 
   ctkVTKScalarsToColorsView view(0);
   view.addColorTransferFunction(ctf);
-  view.fitAxesToBounds();
+  view.setAxesToChartBounds();
   view.show();
 
   ctf->AddRGBPoint(0.6, 0.9686,0.0,0.6941);
-  QTimer autoExit;
+
   if (argc < 2 || QString(argv[1]) != "-I")
     {
-    QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-    autoExit.start(1000);
+    QTimer::singleShot(200, &app, SLOT(quit()));
     }
   return app.exec();
 }

+ 2 - 4
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest2.cpp

@@ -110,14 +110,12 @@ int ctkVTKScalarsToColorsViewTest2(int argc, char * argv [] )
   // add histogram item
   view.addPlot(histogramPlot);
   view.chart()->SetBarWidthFraction(1.);
-  view.fitAxesToBounds();
+  view.setAxesToChartBounds();
   view.show();
 
-  QTimer autoExit;
   if (argc < 2 || QString(argv[1]) != "-I")
     {
-    QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-    autoExit.start(1000);
+    QTimer::singleShot(200, &app, SLOT(quit()));
     }
   return app.exec();
 }

+ 2 - 4
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsViewTest3.cpp

@@ -63,14 +63,12 @@ int ctkVTKScalarsToColorsViewTest3(int argc, char * argv [] )
   ctkVTKScalarsToColorsView view(0);
   // add transfer function item
   view.addCompositeFunction(ctf, opacityFunction);
-  view.fitAxesToBounds();
+  view.setAxesToChartBounds();
   view.show();
 
-  QTimer autoExit;
   if (argc < 2 || QString(argv[1]) != "-I")
     {
-    QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-    autoExit.start(1000);
+    QTimer::singleShot(200, &app, SLOT(quit()));
     }
   return app.exec();
 }

+ 2 - 4
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest1.cpp

@@ -55,14 +55,12 @@ int ctkVTKScalarsToColorsWidgetTest1(int argc, char * argv [] )
   // add transfer function item
   vtkPlot* plot = widget.view()->addOpacityFunction(opacityFunction);
   plot->SetColor(0, 67,  247, 255);
-  widget.view()->fitAxesToBounds();
+  widget.view()->setAxesToChartBounds();
   widget.show();
 
-  QTimer autoExit;
   if (argc < 2 || QString(argv[1]) != "-I")
     {
-    QObject::connect(&autoExit, SIGNAL(timeout()), &app, SLOT(quit()));
-    autoExit.start(1000);
+    QTimer::singleShot(200, &app, SLOT(quit()));
     }
   return app.exec();
 }

+ 75 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest2.cpp

@@ -0,0 +1,75 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QSharedPointer>
+#include <QTimer>
+
+// CTK includes
+#include "ctkVTKScalarsToColorsView.h"
+#include "ctkVTKScalarsToColorsWidget.h"
+
+// VTK includes
+#include <vtkChartXY.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkPiecewiseFunction.h>
+#include <vtkPlot.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKScalarsToColorsWidgetTest2(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  // Transfer Function
+  vtkSmartPointer<vtkColorTransferFunction> ctf =
+    vtkSmartPointer<vtkColorTransferFunction>::New();
+  //
+  ctf->AddRGBPoint(0. , 171./255., 113./255.,   38./255.);
+  ctf->AddRGBPoint(0.2,   38./255., 171./255., 113./255.);
+  ctf->AddRGBPoint(0.4,  113./255., 38./255., 171./255.);
+  ctf->AddRGBPoint(0.6,  171./255., 38./255.,  140./255.);
+  ctf->AddRGBPoint(0.8,  171./255., 46./255., 38./255.);
+
+  // Opacity function
+  vtkSmartPointer<vtkPiecewiseFunction> opacityFunction =
+    vtkSmartPointer<vtkPiecewiseFunction>::New();
+  opacityFunction->AddPoint(0.,0.3);
+  opacityFunction->AddPoint(0.2, 0.55);
+  opacityFunction->AddPoint(0.4,0.87);
+  opacityFunction->AddPoint(0.6, 1.);
+  opacityFunction->AddPoint(0.8, 0.45);
+
+  ctkVTKScalarsToColorsWidget widget(0);
+  // add transfer function item
+  widget.view()->addCompositeFunction(ctf, opacityFunction);
+  widget.view()->setAxesToChartBounds();
+  widget.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 67 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKScalarsToColorsWidgetTest3.cpp

@@ -0,0 +1,67 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QSharedPointer>
+#include <QTimer>
+
+// CTK includes
+#include "ctkVTKScalarsToColorsView.h"
+#include "ctkVTKScalarsToColorsWidget.h"
+
+// VTK includes
+#include <vtkChartXY.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkPiecewiseFunction.h>
+#include <vtkPlot.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKScalarsToColorsWidgetTest3(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  // Transfer Function
+  vtkSmartPointer<vtkColorTransferFunction> ctf =
+    vtkSmartPointer<vtkColorTransferFunction>::New();
+  //
+  ctf->AddRGBPoint(0. , 69./255., 199./255.,   186./255.);
+  ctf->AddRGBPoint(0.2,  172./255., 3./255., 57./255.);
+  ctf->AddRGBPoint(0.4,  169./255., 83./255., 58./255.);
+  ctf->AddRGBPoint(0.6,  43./255., 32./255.,  161./255.);
+  ctf->AddRGBPoint(0.8,  247./255., 158./255., 97./255.);
+  ctf->AddRGBPoint(1.,  183./255., 7./255., 140./255.);
+
+  ctkVTKScalarsToColorsWidget widget(0);
+  // add transfer function item
+  widget.view()->addColorTransferFunction(ctf);
+  widget.view()->setAxesToChartBounds();
+  widget.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 78 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKVolumePropertyWidgetTest1.cpp

@@ -0,0 +1,78 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QDebug>
+#include <QTimer>
+
+// CTK includes
+#include "ctkVTKVolumePropertyWidget.h"
+
+// VTK includes
+#include <vtkColorTransferFunction.h>
+#include <vtkPiecewiseFunction.h>
+#include <vtkSmartPointer.h>
+#include <vtkVolumeProperty.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKVolumePropertyWidgetTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  vtkSmartPointer<vtkColorTransferFunction> ctf =
+    vtkSmartPointer<vtkColorTransferFunction>::New();
+  ctf->AddRGBPoint(0.2, 0.6941,0.76,0., 0.5, 0.);
+  ctf->AddRGBPoint(0.4, 0.,0.6941,0.96);
+  ctf->AddRGBPoint(0.8, 0.9686,0.76,0.);
+
+  vtkSmartPointer<vtkPiecewiseFunction> otf =
+    vtkSmartPointer<vtkPiecewiseFunction>::New();
+  otf->AddPoint(0.2, 0.6941);
+  otf->AddPoint(0.4, 0.641);
+  otf->AddPoint(0.8, 0.9686);
+
+  vtkSmartPointer<vtkPiecewiseFunction> otf2 =
+    vtkSmartPointer<vtkPiecewiseFunction>::New();
+  otf2->AddPoint(0.0, 0.6941);
+  otf2->AddPoint(0.1, 0.641);
+  otf2->AddPoint(0.7, 0.9686);
+
+  vtkSmartPointer<vtkVolumeProperty> volumeProperty =
+    vtkSmartPointer<vtkVolumeProperty>::New();
+  volumeProperty->SetColor(ctf);
+  volumeProperty->SetScalarOpacity(otf);
+
+  ctkVTKVolumePropertyWidget widget;
+  widget.setVolumeProperty(volumeProperty);
+
+  volumeProperty->SetScalarOpacity(otf2);
+
+  widget.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(200, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 93 - 40
Libs/Visualization/VTK/Widgets/ctkVTKChartView.cpp

@@ -19,6 +19,8 @@
 =========================================================================*/
 
 // Qt includes
+#include <QDebug>
+#include <QMouseEvent>
 
 // CTK includes
 #include "ctkLogger.h"
@@ -28,6 +30,7 @@
 #include <vtkAxis.h>
 #include <vtkChartXY.h>
 #include <vtkContext2D.h>
+#include <vtkContextMouseEvent.h>
 #include <vtkContextScene.h>
 #include <vtkContextView.h>
 #include <vtkOpenGLContextDevice2D.h>
@@ -73,6 +76,8 @@ void ctkVTKChartViewPrivate::init()
   //q->GetRenderWindow()->SetMultiSamples(0);
   //vtkOpenGLContextDevice2D::SafeDownCast(this->ContextView->GetContext()->GetDevice())
   //                                       ->SetStringRendererToQt();
+  this->Chart->SetActionToButton(vtkChart::PAN, vtkContextMouseEvent::MIDDLE_BUTTON);
+  this->Chart->SetActionToButton(vtkChart::SELECT, vtkContextMouseEvent::RIGHT_BUTTON);
 }
 
 // ----------------------------------------------------------------------------
@@ -115,89 +120,137 @@ vtkChartXY* ctkVTKChartView::chart()const
 }
 
 // ----------------------------------------------------------------------------
+vtkContextScene* ctkVTKChartView::scene()const
+{
+  Q_D(const ctkVTKChartView);
+  return d->ContextView->GetScene();
+}
+
+// ----------------------------------------------------------------------------
 void ctkVTKChartView::addPlot(vtkPlot* plot)
 {
   Q_D(ctkVTKChartView);
   d->Chart->AddPlot(plot);
+  emit this->plotAdded(plot);
+  this->onChartUpdated();
 }
 
 // ----------------------------------------------------------------------------
-void ctkVTKChartView::fitAxesToBounds()
+void ctkVTKChartView::onChartUpdated()
 {
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKChartView::chartBounds(double* bounds)
+{
+  bounds[0] = bounds[2] = bounds[4] = bounds[6] = VTK_DOUBLE_MAX;
+  bounds[1] = bounds[3] = bounds[5] = bounds[7] = VTK_DOUBLE_MIN;
   vtkChartXY* chart = this->chart();
   const vtkIdType plotCount = chart->GetNumberOfPlots();
-  double extremaBounds[8] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MIN,
-                             VTK_DOUBLE_MAX, VTK_DOUBLE_MIN,
-                             VTK_DOUBLE_MAX, VTK_DOUBLE_MIN};
   for (vtkIdType i = 0; i < plotCount; ++i)
     {
     vtkPlot* plot = chart->GetPlot(i);
 
     int corner = chart->GetPlotCorner(plot);
-    double bounds[4];
-    plot->GetBounds(bounds);
+    double plotBounds[4];
+    plot->GetBounds(plotBounds);
     switch (corner)
       {
       // bottom left
       case 0:
         // x
-        extremaBounds[2] = extremaBounds[2] > bounds[0] ?
-          bounds[0] : extremaBounds[2];
-        extremaBounds[3] = extremaBounds[3] < bounds[1] ?
-          bounds[1] : extremaBounds[3];
+        bounds[2] = bounds[2] > plotBounds[0] ?
+          plotBounds[0] : bounds[2];
+        bounds[3] = bounds[3] < plotBounds[1] ?
+          plotBounds[1] : bounds[3];
         // y
-        extremaBounds[0] = extremaBounds[0] > bounds[2] ?
-          bounds[2] : extremaBounds[0];
-        extremaBounds[1] = extremaBounds[1] < bounds[3] ?
-          bounds[3] : extremaBounds[1];
+        bounds[0] = bounds[0] > plotBounds[2] ?
+          plotBounds[2] : bounds[0];
+        bounds[1] = bounds[1] < plotBounds[3] ?
+          plotBounds[3] : bounds[1];
         break;
       // bottom right
       case 1:
         // x
-        extremaBounds[2] = extremaBounds[2] > bounds[0] ?
-          bounds[0] : extremaBounds[2];
-        extremaBounds[3] = extremaBounds[3] < bounds[1] ?
-          bounds[1] : extremaBounds[3];
+        bounds[2] = bounds[2] > plotBounds[0] ?
+          plotBounds[0] : bounds[2];
+        bounds[3] = bounds[3] < plotBounds[1] ?
+          plotBounds[1] : bounds[3];
         // y
-        extremaBounds[4] = extremaBounds[4] > bounds[2] ?
-          bounds[2] : extremaBounds[4];
-        extremaBounds[5] = extremaBounds[5] < bounds[3] ?
-          bounds[3] : extremaBounds[5];
+        bounds[4] = bounds[4] > plotBounds[2] ?
+          plotBounds[2] : bounds[4];
+        bounds[5] = bounds[5] < plotBounds[3] ?
+          plotBounds[3] : bounds[5];
         break;
       // top right
       case 2:
         // x
-        extremaBounds[6] = extremaBounds[6] > bounds[0] ?
-          bounds[0] : extremaBounds[6];
-        extremaBounds[7] = extremaBounds[7] < bounds[1] ?
-          bounds[1] : extremaBounds[7];
+        bounds[6] = bounds[6] > plotBounds[0] ?
+          plotBounds[0] : bounds[6];
+        bounds[7] = bounds[7] < plotBounds[1] ?
+          plotBounds[1] : bounds[7];
         // y
-        extremaBounds[4] = extremaBounds[4] > bounds[2] ?
-          bounds[2] : extremaBounds[4];
-        extremaBounds[5] = extremaBounds[5] < bounds[3] ?
-          bounds[3] : extremaBounds[5];
+        bounds[4] = bounds[4] > plotBounds[2] ?
+          plotBounds[2] : bounds[4];
+        bounds[5] = bounds[5] < plotBounds[3] ?
+          plotBounds[3] : bounds[5];
         break;
       // top left
       case 3:
         // x
-        extremaBounds[6] = extremaBounds[6] > bounds[0] ?
-          bounds[0] : extremaBounds[6];
-        extremaBounds[7] = extremaBounds[7] < bounds[1] ?
-          bounds[1] : extremaBounds[7];
+        bounds[6] = bounds[6] > plotBounds[0] ?
+          plotBounds[0] : bounds[6];
+        bounds[7] = bounds[7] < plotBounds[1] ?
+          plotBounds[1] : bounds[7];
         // y
-        extremaBounds[0] = extremaBounds[0] > bounds[2] ?
-          bounds[2] : extremaBounds[1];
-        extremaBounds[1] = extremaBounds[0] < bounds[3] ?
-          bounds[3] : extremaBounds[1];
+        bounds[0] = bounds[0] > plotBounds[2] ?
+          plotBounds[2] : bounds[1];
+        bounds[1] = bounds[0] < plotBounds[3] ?
+          plotBounds[3] : bounds[1];
         break;
       }
     }
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKChartView::setAxesToChartBounds()
+{
+  vtkChartXY* chart = this->chart();
+  double bounds[8];
+  this->chartBounds(bounds);
   for (int i = 0; i < chart->GetNumberOfAxes(); ++i)
     {
-    if (extremaBounds[2*i] != VTK_DOUBLE_MAX)
+    if (bounds[2*i] != VTK_DOUBLE_MAX)
       {
-      chart->GetAxis(i)->SetRange(extremaBounds[2*i], extremaBounds[2*i+1]);
+      chart->GetAxis(i)->SetRange(bounds[2*i], bounds[2*i+1]);
       chart->GetAxis(i)->SetBehavior(1);
       }
     }
 }
+
+// ----------------------------------------------------------------------------
+void ctkVTKChartView::boundAxesToChartBounds()
+{
+  vtkChartXY* chart = this->chart();
+  double bounds[8];
+  this->chartBounds(bounds);
+  for (int i = 0; i < chart->GetNumberOfAxes(); ++i)
+    {
+    if (bounds[2*i] != VTK_DOUBLE_MAX)
+      {
+      chart->GetAxis(i)->SetMinimumLimit(bounds[2*i]);
+      chart->GetAxis(i)->SetMaximumLimit(bounds[2*i + 1]);
+      }
+    }
+  emit boundsChanged();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKChartView::mouseDoubleClickEvent(QMouseEvent* event)
+{
+  if (event->button() == Qt::MidButton)
+    {
+    this->setAxesToChartBounds();
+    }
+  this->QVTKWidget::mouseDoubleClickEvent(event);
+}

+ 13 - 2
Libs/Visualization/VTK/Widgets/ctkVTKChartView.h

@@ -30,6 +30,7 @@ class ctkVTKChartViewPrivate;
 #include <QVTKWidget.h>
 
 class vtkChartXY;
+class vtkContextScene;
 class vtkPlot;
 
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKChartView : public QVTKWidget
@@ -42,20 +43,30 @@ public:
   virtual ~ctkVTKChartView();
 
   /// Generic function to add a custom plot. \a plot is added into the chart
-  void addPlot(vtkPlot* plot);
+  virtual void addPlot(vtkPlot* plot);
 
   /// Utility function that returns the view chart. It can be used for customizing
   /// the chart display options (axes, legend...)
   vtkChartXY* chart()const;
+  vtkContextScene* scene()const;
 
   /// Title that appears inside the view
   QString title()const;
   void setTitle(const QString& title);
 
-  void fitAxesToBounds();
+  /// Compute the bounds for the 4 chart axes
+  void chartBounds(double* bounds);
+  void setAxesToChartBounds();
+  void boundAxesToChartBounds();
+
+signals:
+  void plotAdded(vtkPlot* plot);
+  void boundsChanged();
 
 protected:
   QScopedPointer<ctkVTKChartViewPrivate> d_ptr;
+  virtual void mouseDoubleClickEvent(QMouseEvent* event);
+  virtual void onChartUpdated();
 
 private:
   Q_DECLARE_PRIVATE(ctkVTKChartView);

+ 332 - 29
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsView.cpp

@@ -19,6 +19,7 @@
 =========================================================================*/
 
 // Qt includes
+#include <QColorDialog>
 
 // CTK includes
 #include "ctkLogger.h"
@@ -27,8 +28,10 @@
 // VTK includes
 #include <vtkAxis.h>
 #include <vtkChartXY.h>
+#include <vtkColorTransferControlPointsItem.h>
 #include <vtkColorTransferFunction.h>
 #include <vtkColorTransferFunctionItem.h>
+#include <vtkCompositeControlPointsItem.h>
 #include <vtkCompositeTransferFunctionItem.h>
 #include <vtkLookupTable.h>
 #include <vtkLookupTableItem.h>
@@ -48,7 +51,7 @@ protected:
 public:
   ctkVTKScalarsToColorsViewPrivate(ctkVTKScalarsToColorsView& object);
   void init();
-  void updateChart();
+  void updateBounds();
 };
 
 // ----------------------------------------------------------------------------
@@ -67,16 +70,11 @@ void ctkVTKScalarsToColorsViewPrivate::init()
   vtkChartXY* chart = q->chart();
   chart->SetAutoAxes(false);
   chart->SetHiddenAxisBorder(0);
-  chart->GetAxis(0)->SetVisible(false);
-  chart->GetAxis(1)->SetVisible(false);
-  chart->GetAxis(2)->SetVisible(false);
-  chart->GetAxis(3)->SetVisible(false);
-}
-
-// ----------------------------------------------------------------------------
-void ctkVTKScalarsToColorsViewPrivate::updateChart()
-{
-
+  for (int i = 0; i < 4; ++i)
+    {
+    chart->GetAxis(i)->SetVisible(false);
+    }
+  q->onChartUpdated();
 }
 
 // ----------------------------------------------------------------------------
@@ -97,62 +95,367 @@ ctkVTKScalarsToColorsView::~ctkVTKScalarsToColorsView()
 }
 
 // ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView::addPlot(vtkPlot* plot)
+{
+  if (vtkColorTransferControlPointsItem::SafeDownCast(plot))
+    {
+    this->qvtkConnect(plot, vtkControlPointsItem::CurrentPointEditEvent,
+                      this, SLOT(editPoint(vtkObject*, void*)));
+    }
+  this->Superclass::addPlot(plot);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView::onChartUpdated()
+{
+  this->Superclass::onChartUpdated();
+  this->boundAxesToChartBounds();
+  this->setAxesToChartBounds();
+}
+
+// ----------------------------------------------------------------------------
 vtkPlot* ctkVTKScalarsToColorsView::addLookupTable(vtkLookupTable* lut)
 {
-  Q_D(ctkVTKScalarsToColorsView);
   vtkSmartPointer<vtkLookupTableItem> item =
     vtkSmartPointer<vtkLookupTableItem>::New();
   item->SetLookupTable(lut);
   this->addPlot(item);
-  d->updateChart();
   return item;
 }
 // ----------------------------------------------------------------------------
-vtkPlot* ctkVTKScalarsToColorsView::addColorTransferFunction(vtkColorTransferFunction* colorTF)
+vtkPlot* ctkVTKScalarsToColorsView
+::addColorTransferFunction(vtkColorTransferFunction* colorTF,
+                           bool editable)
 {
-  Q_D(ctkVTKScalarsToColorsView);
   vtkSmartPointer<vtkColorTransferFunctionItem> item =
     vtkSmartPointer<vtkColorTransferFunctionItem>::New();
   item->SetColorTransferFunction(colorTF);
   this->addPlot(item);
-  d->updateChart();
+  if (editable)
+    {
+    this->addColorTransferFunctionControlPoints(colorTF);
+    }
   return item;
 }
 
 // ----------------------------------------------------------------------------
-vtkPlot* ctkVTKScalarsToColorsView::addOpacityFunction(vtkPiecewiseFunction* opacityTF)
+vtkPlot* ctkVTKScalarsToColorsView
+::addOpacityFunction(vtkPiecewiseFunction* opacityTF,
+                     bool editable)
+{
+  return this->addPiecewiseFunction(opacityTF, editable);
+}
+
+// ----------------------------------------------------------------------------
+vtkPlot* ctkVTKScalarsToColorsView
+::addPiecewiseFunction(vtkPiecewiseFunction* piecewiseTF,
+                       bool editable)
 {
-  Q_D(ctkVTKScalarsToColorsView);
   vtkSmartPointer<vtkPiecewiseFunctionItem> item =
     vtkSmartPointer<vtkPiecewiseFunctionItem>::New();
-  item->SetPiecewiseFunction(opacityTF);
+  item->SetPiecewiseFunction(piecewiseTF);
   QColor defaultColor = this->palette().highlight().color();
   item->SetColor(defaultColor.redF(), defaultColor.greenF(), defaultColor.blueF());
   item->SetMaskAboveCurve(true);
   this->addPlot(item);
-  vtkSmartPointer<vtkPiecewiseControlPointsItem> controlPointsItem =
-    vtkSmartPointer<vtkPiecewiseControlPointsItem>::New();
-  controlPointsItem->SetPiecewiseFunction(opacityTF);
-  this->addPlot(controlPointsItem);
-  d->updateChart();
+  if (editable)
+    {
+    this->addPiecewiseFunctionControlPoints(piecewiseTF);
+    }
   return item;
 }
 
 // ----------------------------------------------------------------------------
-vtkPlot* ctkVTKScalarsToColorsView::addCompositeFunction(vtkColorTransferFunction* colorTF, vtkPiecewiseFunction* opacityTF)
+vtkPlot* ctkVTKScalarsToColorsView
+::addCompositeFunction(vtkColorTransferFunction* colorTF,
+                       vtkPiecewiseFunction* opacityTF,
+                       bool colorTFEditable, bool opacityTFEditable)
 {
-  Q_D(ctkVTKScalarsToColorsView);
   vtkSmartPointer<vtkCompositeTransferFunctionItem> item =
     vtkSmartPointer<vtkCompositeTransferFunctionItem>::New();
   item->SetColorTransferFunction(colorTF);
   item->SetOpacityFunction(opacityTF);
   item->SetMaskAboveCurve(true);
   this->addPlot(item);
+  if (colorTFEditable && opacityTFEditable)
+    {
+    this->addCompositeFunctionControlPoints(colorTF, opacityTF);
+    }
+  else if (colorTFEditable)
+    {
+    this->addColorTransferFunctionControlPoints(colorTF);
+    }
+  else if (opacityTFEditable)
+    {
+    this->addOpacityFunctionControlPoints(opacityTF);
+    }
+  return item;
+}
+
+// ----------------------------------------------------------------------------
+vtkPlot* ctkVTKScalarsToColorsView
+::addColorTransferFunctionControlPoints(vtkColorTransferFunction* colorTF)
+{
+  vtkSmartPointer<vtkColorTransferControlPointsItem> controlPointsItem =
+    vtkSmartPointer<vtkColorTransferControlPointsItem>::New();
+  controlPointsItem->SetColorTransferFunction(colorTF);
+  this->addPlot(controlPointsItem);
+  return controlPointsItem;
+}
+
+// ----------------------------------------------------------------------------
+vtkPlot* ctkVTKScalarsToColorsView
+::addOpacityFunctionControlPoints(vtkPiecewiseFunction* opacityTF)
+{
+  return this->addPiecewiseFunctionControlPoints(opacityTF);
+}
+
+// ----------------------------------------------------------------------------
+vtkPlot* ctkVTKScalarsToColorsView
+::addCompositeFunctionControlPoints(vtkColorTransferFunction* colorTF,
+                                    vtkPiecewiseFunction* opacityTF)
+{
+  vtkSmartPointer<vtkCompositeControlPointsItem> controlPointsItem =
+    vtkSmartPointer<vtkCompositeControlPointsItem>::New();
+  controlPointsItem->SetColorTransferFunction(colorTF);
+  controlPointsItem->SetOpacityFunction(opacityTF);
+  this->addPlot(controlPointsItem);
+  return controlPointsItem;
+}
+
+// ----------------------------------------------------------------------------
+vtkPlot* ctkVTKScalarsToColorsView
+::addPiecewiseFunctionControlPoints(vtkPiecewiseFunction* piecewiseTF)
+{
   vtkSmartPointer<vtkPiecewiseControlPointsItem> controlPointsItem =
     vtkSmartPointer<vtkPiecewiseControlPointsItem>::New();
-  controlPointsItem->SetPiecewiseFunction(opacityTF);
+  controlPointsItem->SetPiecewiseFunction(piecewiseTF);
   this->addPlot(controlPointsItem);
+  return controlPointsItem;
+}
 
-  d->updateChart();
-  return item;
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView::plots()const
+{
+  QList<vtkPlot*> res;
+  const vtkIdType count = this->chart()->GetNumberOfPlots();
+  for(vtkIdType i = 0; i < count; ++i)
+    {
+    res << this->chart()->GetPlot(i);
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView::lookupTablePlots()const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->plots())
+    {
+    if (vtkLookupTableItem::SafeDownCast(plot))
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView::lookupTablePlots(vtkLookupTable* lut)const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->lookupTablePlots())
+    {
+    vtkLookupTableItem* item = vtkLookupTableItem::SafeDownCast(plot);
+    if (item->GetLookupTable() == lut)
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView::colorTransferFunctionPlots()const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->plots())
+    {
+    if (vtkColorTransferFunctionItem::SafeDownCast(plot) ||
+        vtkColorTransferControlPointsItem::SafeDownCast(plot))
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView
+::colorTransferFunctionPlots(vtkColorTransferFunction* colorTF)const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->colorTransferFunctionPlots())
+    {
+    vtkColorTransferFunctionItem* item =
+      vtkColorTransferFunctionItem::SafeDownCast(plot);
+    if (item
+        && item->GetColorTransferFunction() == colorTF)
+      {
+      res << plot;
+      }
+    vtkColorTransferControlPointsItem* controlPointsItem =
+      vtkColorTransferControlPointsItem::SafeDownCast(plot);
+    if (controlPointsItem
+        && controlPointsItem->GetColorTransferFunction() == colorTF)
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView::opacityFunctionPlots()const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->plots())
+    {
+    if (vtkPiecewiseFunctionItem::SafeDownCast(plot) ||
+        vtkPiecewiseControlPointsItem::SafeDownCast(plot))
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+QList<vtkPlot*> ctkVTKScalarsToColorsView
+::opacityFunctionPlots(vtkPiecewiseFunction* opacityTF)const
+{
+  QList<vtkPlot*> res;
+  foreach(vtkPlot* plot, this->opacityFunctionPlots())
+    {
+    vtkPiecewiseFunctionItem* item =
+      vtkPiecewiseFunctionItem::SafeDownCast(plot);
+    if (item
+        && item->GetPiecewiseFunction() == opacityTF)
+      {
+      res << plot;
+      }
+    vtkPiecewiseControlPointsItem* controlPointsItem =
+      vtkPiecewiseControlPointsItem::SafeDownCast(plot);
+    if (controlPointsItem
+        && controlPointsItem->GetPiecewiseFunction() == opacityTF)
+      {
+      res << plot;
+      }
+    vtkCompositeTransferFunctionItem* compositeItem =
+      vtkCompositeTransferFunctionItem::SafeDownCast(plot);
+    if (compositeItem
+        && compositeItem->GetOpacityFunction() == opacityTF)
+      {
+      res << plot;
+      }
+    vtkCompositeControlPointsItem* compositeControlPointsItem =
+      vtkCompositeControlPointsItem::SafeDownCast(plot);
+    if (compositeControlPointsItem
+        && compositeControlPointsItem->GetOpacityFunction() == opacityTF)
+      {
+      res << plot;
+      }
+    }
+  return res;
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView::setLookuptTableToPlots(vtkLookupTable* lut)
+{
+  foreach(vtkLookupTableItem* plot,
+          this->plots<vtkLookupTableItem>())
+    {
+    plot->SetLookupTable(lut);
+    }
+  this->onChartUpdated();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView
+::setColorTransferFunctionToPlots(vtkColorTransferFunction* colorTF)
+{
+  foreach(vtkColorTransferFunctionItem* plot,
+          this->plots<vtkColorTransferFunctionItem>())
+    {
+    plot->SetColorTransferFunction(colorTF);
+    }
+  foreach(vtkColorTransferControlPointsItem* plot,
+          this->plots<vtkColorTransferControlPointsItem>())
+    {
+    plot->SetColorTransferFunction(colorTF);
+    }
+  this->onChartUpdated();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView
+::setOpacityFunctionToPlots(vtkPiecewiseFunction* opacityTF)
+{
+  this->setPiecewiseFunctionToPlots(opacityTF);
+  foreach(vtkCompositeTransferFunctionItem* plot,
+          this->plots<vtkCompositeTransferFunctionItem>())
+    {
+    plot->SetOpacityFunction(opacityTF);
+    }
+  foreach(vtkCompositeControlPointsItem* plot,
+          this->plots<vtkCompositeControlPointsItem>())
+    {
+    plot->SetOpacityFunction(opacityTF);
+    }
+  this->onChartUpdated();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView
+::setPiecewiseFunctionToPlots(vtkPiecewiseFunction* piecewiseTF)
+{
+  foreach(vtkPiecewiseFunctionItem* plot,
+          this->plots<vtkPiecewiseFunctionItem>())
+    {
+    plot->SetPiecewiseFunction(piecewiseTF);
+    }
+  foreach(vtkPiecewiseControlPointsItem* plot,
+          this->plots<vtkPiecewiseControlPointsItem>())
+    {
+    plot->SetPiecewiseFunction(piecewiseTF);
+    }
+  this->onChartUpdated();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsView::editPoint(vtkObject* caller, void* callData)
+{
+  vtkControlPointsItem* controlPoints = reinterpret_cast<vtkControlPointsItem*>(caller);
+  int pointToEdit = reinterpret_cast<unsigned long>(callData);
+  if (!controlPoints || pointToEdit < 0)
+    {
+    return;
+    }
+  vtkColorTransferControlPointsItem* colorTransferFunctionItem =
+    vtkColorTransferControlPointsItem::SafeDownCast(controlPoints);
+  if (colorTransferFunctionItem)
+    {
+    double xrgbms[6];
+    vtkColorTransferFunction* colorTF = colorTransferFunctionItem->GetColorTransferFunction();
+    colorTF->GetNodeValue(pointToEdit, xrgbms);
+    QColor oldColor = QColor::fromRgbF(xrgbms[0], xrgbms[1], xrgbms[2]);
+    QColor newColor = QColorDialog::getColor(oldColor, this);
+    if (newColor.isValid())
+      {
+      xrgbms[1] = newColor.redF();
+      xrgbms[2] = newColor.greenF();
+      xrgbms[3] = newColor.blueF();
+      colorTF->SetNodeValue(pointToEdit, xrgbms);
+      }
+    }
 }

+ 59 - 6
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsView.h

@@ -22,36 +22,89 @@
 #define __ctkVTKScalarsToColorsView_h
 
 // CTK includes
-#include <ctkPimpl.h>
 #include "ctkVTKChartView.h"
+#include "ctkVTKObject.h"
 class ctkVTKScalarsToColorsViewPrivate;
 
 // VTK includes
 #include <QVTKWidget.h>
+#include <vtkChartXY.h>
 
 class vtkColorTransferFunction;
 class vtkLookupTable;
 class vtkPiecewiseFunction;
 
-class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKScalarsToColorsView : public ctkVTKChartView
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKScalarsToColorsView
+  : public ctkVTKChartView
 {
   Q_OBJECT
-
+  QVTK_OBJECT
 public:
+  typedef ctkVTKChartView Superclass;
   ctkVTKScalarsToColorsView(QWidget* parent = 0);
   virtual ~ctkVTKScalarsToColorsView();
 
+  virtual void addPlot(vtkPlot* plot);
+
   vtkPlot* addLookupTable(vtkLookupTable* lut);
-  vtkPlot* addColorTransferFunction(vtkColorTransferFunction* colorTF);
-  vtkPlot* addOpacityFunction(vtkPiecewiseFunction* opacityTF);
-  vtkPlot* addCompositeFunction(vtkColorTransferFunction* colorTF, vtkPiecewiseFunction* opacityTF);
+  vtkPlot* addColorTransferFunction(vtkColorTransferFunction* colorTF, bool editable = true);
+  vtkPlot* addOpacityFunction(vtkPiecewiseFunction* opacityTF, bool editable = true);
+  vtkPlot* addCompositeFunction(vtkColorTransferFunction* colorTF,
+                                vtkPiecewiseFunction* opacityTF,
+                                bool colorTFEditable = true,
+                                bool opacityTFEditable = true);
+  vtkPlot* addPiecewiseFunction(vtkPiecewiseFunction* piecewiseTF, bool editable = true);
+
+  vtkPlot* addColorTransferFunctionControlPoints(vtkColorTransferFunction* colorTF);
+  vtkPlot* addOpacityFunctionControlPoints(vtkPiecewiseFunction* opacityTF);
+  vtkPlot* addCompositeFunctionControlPoints(vtkColorTransferFunction* colorTF,
+                                             vtkPiecewiseFunction* opacityTF);
+  vtkPlot* addPiecewiseFunctionControlPoints(vtkPiecewiseFunction* piecewiseTF);
+
+  QList<vtkPlot*> plots()const;
+  template<class T>
+  QList<T*> plots()const;
+  QList<vtkPlot*> lookupTablePlots()const;
+  QList<vtkPlot*> lookupTablePlots(vtkLookupTable* lut)const;
+  QList<vtkPlot*> colorTransferFunctionPlots()const;
+  QList<vtkPlot*> colorTransferFunctionPlots(vtkColorTransferFunction* colorTF)const;
+  QList<vtkPlot*> opacityFunctionPlots()const;
+  QList<vtkPlot*> opacityFunctionPlots(vtkPiecewiseFunction* opacityTF)const;
+
+  void setLookuptTableToPlots(vtkLookupTable* lut);
+  void setColorTransferFunctionToPlots(vtkColorTransferFunction* colorTF);
+  void setOpacityFunctionToPlots(vtkPiecewiseFunction* opacityTF);
+  void setPiecewiseFunctionToPlots(vtkPiecewiseFunction* piecewiseTF);
+
+public slots:
+  void editPoint(vtkObject* plot, void * pointId);
 
 protected:
   QScopedPointer<ctkVTKScalarsToColorsViewPrivate> d_ptr;
 
+  virtual void onChartUpdated();
+
 private:
   Q_DECLARE_PRIVATE(ctkVTKScalarsToColorsView);
   Q_DISABLE_COPY(ctkVTKScalarsToColorsView);
 };
 
+// ----------------------------------------------------------------------------
+template<class T>
+QList<T*> ctkVTKScalarsToColorsView::plots()const
+{
+  QList<T*> res;
+  const vtkIdType count = this->chart()->GetNumberOfPlots();
+  for(vtkIdType i = 0; i < count; ++i)
+    {
+    vtkPlot* plot = this->chart()->GetPlot(i);
+    if (T::SafeDownCast(plot) != 0)
+      {
+      res << T::SafeDownCast(plot);
+      }
+    }
+  return res;
+}
+
+
 #endif

+ 314 - 5
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.cpp

@@ -19,6 +19,7 @@
 =========================================================================*/
 
 // Qt includes
+#include <QDebug>
 
 // CTK includes
 #include "ctkLogger.h"
@@ -29,9 +30,12 @@
 // VTK includes
 #include <vtkAxis.h>
 #include <vtkChartXY.h>
+#include <vtkColorTransferControlPointsItem.h>
 #include <vtkColorTransferFunction.h>
 #include <vtkColorTransferFunctionItem.h>
+#include <vtkCompositeControlPointsItem.h>
 #include <vtkCompositeTransferFunctionItem.h>
+#include <vtkContextScene.h>
 #include <vtkLookupTable.h>
 #include <vtkLookupTableItem.h>
 #include <vtkPiecewiseControlPointsItem.h>
@@ -45,25 +49,60 @@ static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKScalarsToC
 class ctkVTKScalarsToColorsWidgetPrivate:
   public Ui_ctkVTKScalarsToColorsWidget
 {
+   Q_DECLARE_PUBLIC(ctkVTKScalarsToColorsWidget);
+protected:
+  ctkVTKScalarsToColorsWidget* const q_ptr;
 public:
-  ctkVTKScalarsToColorsWidgetPrivate();
+  ctkVTKScalarsToColorsWidgetPrivate(ctkVTKScalarsToColorsWidget& object);
   void setupUi(QWidget* widget);
+  vtkControlPointsItem* CurrentControlPointsItem;
 };
 
 // ----------------------------------------------------------------------------
 // ctkVTKScalarsToColorsWidgetPrivate methods
 
 // ----------------------------------------------------------------------------
-ctkVTKScalarsToColorsWidgetPrivate::ctkVTKScalarsToColorsWidgetPrivate()
+ctkVTKScalarsToColorsWidgetPrivate::ctkVTKScalarsToColorsWidgetPrivate(
+  ctkVTKScalarsToColorsWidget& object)
+  : q_ptr(&object)
 {
+  this->CurrentControlPointsItem = 0;
 }
 
 // ----------------------------------------------------------------------------
 void ctkVTKScalarsToColorsWidgetPrivate::setupUi(QWidget* widget)
 {
+  Q_Q(ctkVTKScalarsToColorsWidget);
   this->Ui_ctkVTKScalarsToColorsWidget::setupUi(widget);
-  this->PSpinBox->setValue(0.4);
-  this->VSpinBox->setValue(0.87);
+  QObject::connect(this->View, SIGNAL(plotAdded(vtkPlot*)),
+                   q, SLOT(onPlotAdded(vtkPlot*)));
+  QObject::connect(this->View, SIGNAL(boundsChanged()),
+                   q, SLOT(onBoundsChanged()));
+
+  this->PointIdSpinBox->setSpecialValueText("None");
+  QObject::connect(this->PointIdSpinBox, SIGNAL(valueChanged(int)),
+                   q, SLOT(onCurrentPointChanged(int)));
+  this->PointIdSpinBox->setValue(-1);
+  QObject::connect(this->ColorPickerButton, SIGNAL(colorChanged(const QColor&)),
+                   q, SLOT(onColorChanged(const QColor&)));
+  QObject::connect(this->OpacitySpinBox, SIGNAL(valueChanged(double)),
+                   q, SLOT(onOpacityChanged(double)));
+  QObject::connect(this->MidPointSpinBox, SIGNAL(valueChanged(double)),
+                   q, SLOT(onMidPointChanged(double)));
+  QObject::connect(this->SharpnessSpinBox, SIGNAL(valueChanged(double)),
+                   q, SLOT(onSharpnessChanged(double)));
+  this->ColorPickerButton->setVisible(false);
+  this->OpacityLabel->setVisible(false);
+  this->OpacitySpinBox->setVisible(false);
+  QObject::connect(this->XRangeSlider, SIGNAL(valuesChanged(double, double)),
+                   q, SLOT(onXRangeChanged(double, double)));
+  QObject::connect(this->YRangeSlider, SIGNAL(valuesChanged(double, double)),
+                   q, SLOT(onYRangeChanged(double, double)));
+  q->qvtkConnect(this->View->chart()->GetAxis(0),vtkCommand::ModifiedEvent,
+                    q, SLOT(onAxesModified()));
+  q->qvtkConnect(this->View->chart()->GetAxis(1),vtkCommand::ModifiedEvent,
+                    q, SLOT(onAxesModified()));
+
 }
 
 // ----------------------------------------------------------------------------
@@ -72,7 +111,7 @@ void ctkVTKScalarsToColorsWidgetPrivate::setupUi(QWidget* widget)
 // ----------------------------------------------------------------------------
 ctkVTKScalarsToColorsWidget::ctkVTKScalarsToColorsWidget(QWidget* parentWidget)
   :QWidget(parentWidget)
-  , d_ptr(new ctkVTKScalarsToColorsWidgetPrivate)
+   , d_ptr(new ctkVTKScalarsToColorsWidgetPrivate(*this))
 {
   Q_D(ctkVTKScalarsToColorsWidget);
   d->setupUi(this);
@@ -89,3 +128,273 @@ ctkVTKScalarsToColorsView* ctkVTKScalarsToColorsWidget::view()const
   Q_D(const ctkVTKScalarsToColorsWidget);
   return d->View;
 }
+
+// ----------------------------------------------------------------------------
+bool ctkVTKScalarsToColorsWidget::isHorizontalSliderVisible()const
+{
+  Q_D(const ctkVTKScalarsToColorsWidget);
+  return d->XRangeSlider->isVisibleTo(
+    const_cast<ctkVTKScalarsToColorsWidget*>(this));
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setHorizontalSliderVisible(bool visible)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  d->XRangeSlider->setVisible(visible);
+}
+
+// ----------------------------------------------------------------------------
+bool ctkVTKScalarsToColorsWidget::isVerticalSliderVisible()const
+{
+  Q_D(const ctkVTKScalarsToColorsWidget);
+  return d->YRangeSlider->isVisibleTo(
+    const_cast<ctkVTKScalarsToColorsWidget*>(this));
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setVerticalSliderVisible(bool visible)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  d->YRangeSlider->setVisible(visible);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onPlotAdded(vtkPlot* plot)
+{
+  if (vtkControlPointsItem::SafeDownCast(plot))
+    {
+    this->qvtkConnect(plot, vtkControlPointsItem::CurrentPointChangedEvent,
+                      this, SLOT(setCurrentPoint(vtkObject*, void*)));
+    }
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onBoundsChanged()
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  double bounds[8];
+  d->View->chartBounds(bounds);
+  d->XRangeSlider->setMinimum(bounds[vtkAxis::BOTTOM * 2]);
+  d->XRangeSlider->setMaximum(bounds[vtkAxis::BOTTOM * 2 + 1]);
+  d->YRangeSlider->setMinimum(bounds[vtkAxis::LEFT * 2]);
+  d->YRangeSlider->setMaximum(bounds[vtkAxis::LEFT * 2 + 1]);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setCurrentPoint(vtkObject* caller, void* callData)
+{
+  vtkControlPointsItem* controlPoints = reinterpret_cast<vtkControlPointsItem*>(caller);
+  long newPoint = reinterpret_cast<long>(callData);
+  if (!controlPoints || newPoint < -1)
+    {
+    return;
+    }
+  this->setCurrentControlPointsItem(controlPoints);
+  this->setCurrentPoint(newPoint);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setCurrentPoint(int newPoint)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  d->PointIdSpinBox->setValue(newPoint);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::setCurrentControlPointsItem(vtkControlPointsItem* item)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  if (d->CurrentControlPointsItem == item)
+    {
+    return;
+    }
+  this->qvtkReconnect(d->CurrentControlPointsItem, item, vtkCommand::ModifiedEvent,
+                      this, SLOT(updateCurrentPoint()));
+  this->qvtkReconnect(d->CurrentControlPointsItem ?
+                      d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(0),
+                      item ? item->GetXAxis() : d->View->chart()->GetAxis(0),
+                      vtkCommand::ModifiedEvent,
+                      this, SLOT(onAxesModified()));
+  this->qvtkReconnect(d->CurrentControlPointsItem ?
+                      d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(1),
+                      item ? item->GetYAxis() : d->View->chart()->GetAxis(1),
+                      vtkCommand::ModifiedEvent,
+                      this, SLOT(onAxesModified()));
+  d->CurrentControlPointsItem = item;
+  if (item)
+    {
+    d->ColorPickerButton->setVisible(
+      vtkColorTransferControlPointsItem::SafeDownCast(item) != 0 ||
+      vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
+    d->OpacityLabel->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
+                                vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
+    d->OpacitySpinBox->setVisible(vtkPiecewiseControlPointsItem::SafeDownCast(item) != 0 ||
+                                  vtkCompositeControlPointsItem::SafeDownCast(item) != 0);
+    this->onAxesModified();
+    }
+  d->PointIdSpinBox->setEnabled(item != 0);
+  d->PointIdSpinBox->setMaximum((item ? item->GetNumberOfPoints() : 0) - 1);
+  d->PointIdSpinBox->setValue(item ? item->GetCurrentPoint() : -1);
+  this->updateCurrentPoint();
+}
+
+// ----------------------------------------------------------------------------
+vtkControlPointsItem* ctkVTKScalarsToColorsWidget::currentControlPointsItem()const
+{
+  Q_D(const ctkVTKScalarsToColorsWidget);
+  return d->CurrentControlPointsItem;
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onCurrentPointChanged(int currentPoint)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  if (d->CurrentControlPointsItem)
+    {
+    d->CurrentControlPointsItem->SetCurrentPoint(currentPoint);
+    }
+
+  d->ColorPickerButton->setEnabled(currentPoint != -1);
+  d->OpacitySpinBox->setEnabled(currentPoint != -1);
+  d->MidPointSpinBox->setEnabled(currentPoint != -1);
+  d->SharpnessSpinBox->setEnabled(currentPoint != -1);
+
+  if (d->CurrentControlPointsItem)
+    {
+    this->updateCurrentPoint();
+    }
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::updateCurrentPoint()
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  Q_ASSERT(d->CurrentControlPointsItem);
+  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());
+  d->PointIdSpinBox->setMaximum((d->CurrentControlPointsItem ?
+                                 d->CurrentControlPointsItem->GetNumberOfPoints() : 0) - 1);
+
+  int pointId = d->PointIdSpinBox->value();
+  if (pointId == -1)
+    {
+    return;
+    }
+
+  double point[4];
+  d->CurrentControlPointsItem->GetControlPoint(pointId, point);
+  d->OpacitySpinBox->setValue(point[1]);
+  d->MidPointSpinBox->setValue(point[2]);
+  d->SharpnessSpinBox->setValue(point[3]);
+
+  vtkColorTransferControlPointsItem* colorControlPoints =
+    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
+  if (colorControlPoints)
+    {
+    vtkColorTransferFunction* colorTF =
+      colorControlPoints->GetColorTransferFunction();
+    double xrgbms[6];
+    colorTF->GetNodeValue(d->PointIdSpinBox->value(), xrgbms);
+    QColor color = QColor::fromRgbF(xrgbms[1], xrgbms[2], xrgbms[3]);
+    d->ColorPickerButton->setColor(color);
+    }
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onColorChanged(const QColor& color)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  if (!color.isValid())
+    {
+    return;
+    }
+  Q_ASSERT(d->CurrentControlPointsItem);
+  Q_ASSERT(d->PointIdSpinBox->value() != -1);
+  Q_ASSERT(d->PointIdSpinBox->value() == d->CurrentControlPointsItem->GetCurrentPoint());
+
+  vtkColorTransferControlPointsItem* colorControlPoints =
+    vtkColorTransferControlPointsItem::SafeDownCast(d->CurrentControlPointsItem);
+  if (colorControlPoints)
+    {
+    vtkColorTransferFunction* colorTF =
+      colorControlPoints->GetColorTransferFunction();
+    double point[6];
+    colorTF->GetNodeValue(d->PointIdSpinBox->value(), point);
+    point[1] = color.redF();
+    point[2] = color.greenF();
+    point[3] = color.blueF();
+    colorTF->SetNodeValue(d->PointIdSpinBox->value(), point);
+    }
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onOpacityChanged(double opacity)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  Q_ASSERT(d->CurrentControlPointsItem);
+
+  double point[4];
+  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
+  point[1] = opacity;
+  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onMidPointChanged(double midPoint)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  Q_ASSERT(d->CurrentControlPointsItem);
+
+  double point[4];
+  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
+  point[2] = midPoint;
+  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onSharpnessChanged(double sharpness)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  Q_ASSERT(d->CurrentControlPointsItem);
+
+  double point[4];
+  d->CurrentControlPointsItem->GetControlPoint(d->PointIdSpinBox->value(), point);
+  point[3] = sharpness;
+  d->CurrentControlPointsItem->SetControlPoint(d->PointIdSpinBox->value(), point);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onXRangeChanged(double min, double max)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  vtkAxis* xAxis = d->CurrentControlPointsItem ?
+    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
+  Q_ASSERT(xAxis);
+  xAxis->SetRange(min, max);
+  d->View->scene()->SetDirty(true);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onYRangeChanged(double min, double max)
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  vtkAxis* yAxis = d->CurrentControlPointsItem ?
+    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
+  Q_ASSERT(yAxis);
+  yAxis->SetRange(min, max);
+  d->View->scene()->SetDirty(true);
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKScalarsToColorsWidget::onAxesModified()
+{
+  Q_D(ctkVTKScalarsToColorsWidget);
+  vtkAxis* xAxis = d->CurrentControlPointsItem ?
+    d->CurrentControlPointsItem->GetXAxis() : d->View->chart()->GetAxis(vtkAxis::BOTTOM);
+  Q_ASSERT(xAxis);
+  d->XRangeSlider->setValues(xAxis->GetMinimum(), xAxis->GetMaximum());
+  vtkAxis* yAxis = d->CurrentControlPointsItem ?
+    d->CurrentControlPointsItem->GetYAxis() : d->View->chart()->GetAxis(vtkAxis::LEFT);
+  Q_ASSERT(yAxis);
+  d->YRangeSlider->setValues(yAxis->GetMinimum(), yAxis->GetMaximum());
+}

+ 31 - 3
Libs/Visualization/VTK/Widgets/ctkVTKScalarsToColorsWidget.h

@@ -25,23 +25,51 @@
 #include <QWidget>
 
 // CTK includes
-#include <ctkPimpl.h>
+#include <ctkVTKObject.h>
 #include "ctkVisualizationVTKWidgetsExport.h"
 class ctkVTKScalarsToColorsView;
 class ctkVTKScalarsToColorsWidgetPrivate;
 
 // VTK includes
-#include <QVTKWidget.h>
+class vtkControlPointsItem;
+class vtkPlot;
 
 class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKScalarsToColorsWidget : public QWidget
 {
   Q_OBJECT
-
+  QVTK_OBJECT
+  Q_PROPERTY(bool horizontalSliderVisible READ isHorizontalSliderVisible WRITE setHorizontalSliderVisible)
+  Q_PROPERTY(bool verticalSliderVisible READ isVerticalSliderVisible WRITE setVerticalSliderVisible)
 public:
   ctkVTKScalarsToColorsWidget(QWidget* parent = 0);
   virtual ~ctkVTKScalarsToColorsWidget();
 
   ctkVTKScalarsToColorsView* view()const;
+  vtkControlPointsItem* currentControlPointsItem()const;
+
+  bool isHorizontalSliderVisible()const;
+  void setHorizontalSliderVisible(bool visible);
+
+  bool isVerticalSliderVisible()const;
+  void setVerticalSliderVisible(bool visible);
+
+public slots:
+  void setCurrentControlPointsItem(vtkControlPointsItem* item);
+  void setCurrentPoint(int pointId);
+
+protected slots:
+  void onPlotAdded(vtkPlot*);
+  void onBoundsChanged();
+  void setCurrentPoint(vtkObject* controlPointsItem, void* pointId);
+  void updateCurrentPoint();
+  void onCurrentPointChanged(int pointId);
+  void onColorChanged(const QColor& color);
+  void onOpacityChanged(double opacity);
+  void onMidPointChanged(double midPoint);
+  void onSharpnessChanged(double sharpness);
+  void onXRangeChanged(double min, double max);
+  void onYRangeChanged(double min, double max);
+  void onAxesModified();
 protected:
   QScopedPointer<ctkVTKScalarsToColorsWidgetPrivate> d_ptr;
 

+ 156 - 0
Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.cpp

@@ -0,0 +1,156 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QDebug>
+
+// CTK includes
+#include "ctkLogger.h"
+#include "ctkVTKScalarsToColorsView.h"
+#include "ctkVTKVolumePropertyWidget.h"
+#include "ui_ctkVTKVolumePropertyWidget.h"
+
+// VTK includes
+#include <vtkColorTransferControlPointsItem.h>
+#include <vtkColorTransferFunction.h>
+#include <vtkColorTransferFunctionItem.h>
+#include <vtkCompositeControlPointsItem.h>
+#include <vtkCompositeTransferFunctionItem.h>
+#include <vtkContextScene.h>
+#include <vtkLookupTable.h>
+#include <vtkLookupTableItem.h>
+#include <vtkPiecewiseControlPointsItem.h>
+#include <vtkPiecewiseFunction.h>
+#include <vtkPiecewiseFunctionItem.h>
+#include <vtkVolumeProperty.h>
+
+//----------------------------------------------------------------------------
+static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkVTKVolumePropertyWidget");
+//----------------------------------------------------------------------------
+
+class ctkVTKVolumePropertyWidgetPrivate:
+  public Ui_ctkVTKVolumePropertyWidget
+{
+   Q_DECLARE_PUBLIC(ctkVTKVolumePropertyWidget);
+protected:
+  ctkVTKVolumePropertyWidget* const q_ptr;
+public:
+  ctkVTKVolumePropertyWidgetPrivate(ctkVTKVolumePropertyWidget& object);
+  void setupUi(QWidget* widget);
+
+  vtkVolumeProperty* VolumeProperty;
+};
+
+// ----------------------------------------------------------------------------
+// ctkVTKVolumePropertyWidgetPrivate methods
+
+// ----------------------------------------------------------------------------
+ctkVTKVolumePropertyWidgetPrivate::ctkVTKVolumePropertyWidgetPrivate(
+  ctkVTKVolumePropertyWidget& object)
+  : q_ptr(&object)
+{
+  this->VolumeProperty = 0;
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKVolumePropertyWidgetPrivate::setupUi(QWidget* widget)
+{
+  //Q_Q(ctkVTKVolumePropertyWidget);
+  this->Ui_ctkVTKVolumePropertyWidget::setupUi(widget);
+
+  this->ScalarOpacityWidget->view()->addCompositeFunction(0, 0, false, true);
+  this->ScalarColorWidget->view()->addColorTransferFunction(0);
+  this->GradientWidget->view()->addPiecewiseFunction(0);
+
+  this->GradientGroupBox->setCollapsed(true);
+  this->AdvancedGroupBox->setCollapsed(true);
+}
+
+// ----------------------------------------------------------------------------
+// ctkVTKVolumePropertyWidget methods
+
+// ----------------------------------------------------------------------------
+ctkVTKVolumePropertyWidget::ctkVTKVolumePropertyWidget(QWidget* parentWidget)
+  :QWidget(parentWidget)
+   , d_ptr(new ctkVTKVolumePropertyWidgetPrivate(*this))
+{
+  Q_D(ctkVTKVolumePropertyWidget);
+  d->setupUi(this);
+}
+
+// ----------------------------------------------------------------------------
+ctkVTKVolumePropertyWidget::~ctkVTKVolumePropertyWidget()
+{
+}
+
+// ----------------------------------------------------------------------------
+vtkVolumeProperty* ctkVTKVolumePropertyWidget::volumeProperty()const
+{
+  Q_D(const ctkVTKVolumePropertyWidget);
+  return d->VolumeProperty;
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKVolumePropertyWidget
+::setVolumeProperty(vtkVolumeProperty* newVolumeProperty)
+{
+  Q_D(ctkVTKVolumePropertyWidget);
+  this->qvtkReconnect(d->VolumeProperty, newVolumeProperty, vtkCommand::ModifiedEvent,
+                      this, SLOT(updateFromVolumeProperty()));
+  d->VolumeProperty = newVolumeProperty;
+  this->updateFromVolumeProperty();
+}
+
+// ----------------------------------------------------------------------------
+void ctkVTKVolumePropertyWidget::updateFromVolumeProperty()
+{
+  Q_D(ctkVTKVolumePropertyWidget);
+  vtkColorTransferFunction* colorTransferFunction = 0;
+  vtkPiecewiseFunction* opacityFunction = 0;
+  vtkPiecewiseFunction* gradientFunction = 0;
+  if (d->VolumeProperty)
+    {
+    colorTransferFunction =
+      d->VolumeProperty->GetRGBTransferFunction()->GetSize() ?
+      d->VolumeProperty->GetRGBTransferFunction() : 0;
+    opacityFunction =
+      d->VolumeProperty->GetScalarOpacity()->GetSize() ?
+      d->VolumeProperty->GetScalarOpacity() : 0;
+    gradientFunction =
+      d->VolumeProperty->GetGradientOpacity()->GetSize() ?
+      d->VolumeProperty->GetGradientOpacity() : 0;
+    }
+
+  d->ScalarOpacityWidget->view()->setOpacityFunctionToPlots(opacityFunction);
+  d->ScalarOpacityWidget->view()->setColorTransferFunctionToPlots(colorTransferFunction);
+  d->ScalarColorWidget->view()->setColorTransferFunctionToPlots(colorTransferFunction);
+  d->GradientWidget->view()->setPiecewiseFunctionToPlots(gradientFunction);
+
+  if (d->VolumeProperty)
+    {
+    d->MaterialPropertyLabel->setAmbient(d->VolumeProperty->GetAmbient());
+    d->MaterialPropertyLabel->setDiffuse(d->VolumeProperty->GetDiffuse());
+    d->MaterialPropertyLabel->setSpecular(d->VolumeProperty->GetSpecular());
+    d->MaterialPropertyLabel->setSpecularPower(d->VolumeProperty->GetSpecularPower());
+    d->InterpolationComboBox->setCurrentIndex(
+      d->VolumeProperty->GetInterpolationType() == VTK_NEAREST_INTERPOLATION ? 0 : 1);
+    }
+}
+

+ 60 - 0
Libs/Visualization/VTK/Widgets/ctkVTKVolumePropertyWidget.h

@@ -0,0 +1,60 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKVolumePropertyWidget_h
+#define __ctkVTKVolumePropertyWidget_h
+
+//Qt includes
+#include <QWidget>
+
+// CTK includes
+#include <ctkVTKObject.h>
+#include "ctkVisualizationVTKWidgetsExport.h"
+class ctkVTKVolumePropertyWidgetPrivate;
+
+// VTK includes
+class vtkVolumeProperty;
+
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKVolumePropertyWidget
+  : public QWidget
+{
+  Q_OBJECT
+  QVTK_OBJECT
+
+public:
+  ctkVTKVolumePropertyWidget(QWidget* parent = 0);
+  virtual ~ctkVTKVolumePropertyWidget();
+
+  vtkVolumeProperty* volumeProperty()const;
+
+public slots:
+  void setVolumeProperty(vtkVolumeProperty* volumeProperty);
+
+protected slots:
+  void updateFromVolumeProperty();
+protected:
+  QScopedPointer<ctkVTKVolumePropertyWidgetPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkVTKVolumePropertyWidget);
+  Q_DISABLE_COPY(ctkVTKVolumePropertyWidget);
+};
+
+#endif