diff --git a/CMakeLists.txt b/CMakeLists.txt
index 159f407..3cd340d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,8 +67,8 @@ set(UI_RESOURCES
# Create executable
qt5_wrap_ui(UISrcs ${UI_FILES} )
# CMAKE_AUTOMOC is ON so the MOC headers will be automatically wrapped.
-add_executable(Segmentor MACOSX_BUNDLE WIN32 ${CXX_FILES} ${UISrcs} ${QT_WRAP} ${UI_RESOURCES})
-#add_executable(Segmentor MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${QT_WRAP} ${UI_RESOURCES})
+#add_executable(Segmentor MACOSX_BUNDLE WIN32 ${CXX_FILES} ${UISrcs} ${QT_WRAP} ${UI_RESOURCES})
+add_executable(Segmentor MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${QT_WRAP} ${UI_RESOURCES})
qt5_use_modules(Segmentor Core Gui)
target_link_libraries(Segmentor ${VTK_LIBRARIES})
install(TARGETS Segmentor
diff --git a/qt/MainWindow.cxx b/qt/MainWindow.cxx
index c5d898f..2f33714 100644
--- a/qt/MainWindow.cxx
+++ b/qt/MainWindow.cxx
@@ -117,20 +117,20 @@ MainWindow::MainWindow() {
brushRadiusSpinBox->setToolTip("Adjust brush radius (left / right arrow)");
// Overlay opacity shortcut
- QShortcut* overlayUp = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right), this);
- QShortcut* overlayDown = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left), this);
+ QShortcut* overlayOpacityUp = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Right), this);
+ QShortcut* overlayOpacityDown = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Left), this);
- QObject::connect(overlayUp, &QShortcut::activated, this, &MainWindow::on_overlayUp);
- QObject::connect(overlayDown, &QShortcut::activated, this, &MainWindow::on_overlayDown);
- QObject::connect(this, &MainWindow::overlayChanged, settingsDialog, &SettingsDialog::on_overlayChanged);
+ QObject::connect(overlayOpacityUp, &QShortcut::activated, this, &MainWindow::on_overlayOpacityUp);
+ QObject::connect(overlayOpacityDown, &QShortcut::activated, this, &MainWindow::on_overlayOpacityDown);
+ QObject::connect(this, &MainWindow::overlayOpacityChanged, settingsDialog, &SettingsDialog::on_overlayOpacityChanged);
- // Region opacity shortcut
- QShortcut* opacityUp = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right), this);
- QShortcut* opacityDown = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left), this);
+ // Surface opacity shortcut
+ QShortcut* surfaceOpacityUp = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right), this);
+ QShortcut* surfaceOpacityDown = new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left), this);
- QObject::connect(opacityUp, &QShortcut::activated, this, &MainWindow::on_opacityUp);
- QObject::connect(opacityDown, &QShortcut::activated, this, &MainWindow::on_opacityDown);
- QObject::connect(this, &MainWindow::opacityChanged, settingsDialog, &SettingsDialog::on_opacityChanged);
+ QObject::connect(surfaceOpacityUp, &QShortcut::activated, this, &MainWindow::on_surfaceOpacityUp);
+ QObject::connect(surfaceOpacityDown, &QShortcut::activated, this, &MainWindow::on_surfaceOpacityDown);
+ QObject::connect(this, &MainWindow::surfaceOpacityChanged, settingsDialog, &SettingsDialog::on_surfaceOpacityChanged);
// 2D/3D toggle
QShortcut* toggleView = new QShortcut(QKeySequence("t"), this);
@@ -861,40 +861,40 @@ void MainWindow::on_regionColor(int label, QColor color) {
visualizationContainer->SetRegionColor((unsigned short)label, color.redF(), color.greenF(), color.blueF());
}
-void MainWindow::on_overlayDown() {
+void MainWindow::on_overlayOpacityDown() {
SliceView* sliceView = visualizationContainer->GetSliceView();
double value = qMax(sliceView->GetOverlayOpacity() - 0.1, 0.0);
sliceView->SetOverlayOpacity(value);
- emit overlayChanged(value);
+ emit overlayOpacityChanged(value);
}
-void MainWindow::on_overlayUp() {
+void MainWindow::on_overlayOpacityUp() {
SliceView* sliceView = visualizationContainer->GetSliceView();
double value = qMin(sliceView->GetOverlayOpacity() + 0.1, 1.0);
sliceView->SetOverlayOpacity(value);
- emit overlayChanged(value);
+ emit overlayOpacityChanged(value);
}
-void MainWindow::on_opacityDown() {
+void MainWindow::on_surfaceOpacityDown() {
double value = qMax(visualizationContainer->GetVolumeView()->GetVisibleOpacity() - 0.1, 0.0);
visualizationContainer->SetVisibleOpacity(value);
- emit opacityChanged(value);
+ emit surfaceOpacityChanged(value);
}
-void MainWindow::on_opacityUp() {
+void MainWindow::on_surfaceOpacityUp() {
double value = qMin(visualizationContainer->GetVolumeView()->GetVisibleOpacity() + 0.1, 1.0);
visualizationContainer->SetVisibleOpacity(value);
- emit opacityChanged(value);
+ emit surfaceOpacityChanged(value);
}
void MainWindow::on_brushRadiusDown() {
diff --git a/qt/MainWindow.h b/qt/MainWindow.h
index 29b8cd1..63ae566 100644
--- a/qt/MainWindow.h
+++ b/qt/MainWindow.h
@@ -132,18 +132,18 @@ public slots:
virtual void on_regionColor(int label, QColor color);
// Shortcuts for settings
- virtual void on_overlayDown();
- virtual void on_overlayUp();
- virtual void on_opacityDown();
- virtual void on_opacityUp();
+ virtual void on_overlayOpacityDown();
+ virtual void on_overlayOpacityUp();
+ virtual void on_surfaceOpacityDown();
+ virtual void on_surfaceOpacityUp();
virtual void on_brushRadiusDown();
virtual void on_brushRadiusUp();
signals:
void windowLevelChanged(double window, double value);
- void overlayChanged(double value);
- void opacityChanged(double value);
+ void overlayOpacityChanged(double value);
+ void surfaceOpacityChanged(double value);
protected:
// The visualization container
diff --git a/qt/SettingsDialog.cxx b/qt/SettingsDialog.cxx
index b210859..1b2aee8 100644
--- a/qt/SettingsDialog.cxx
+++ b/qt/SettingsDialog.cxx
@@ -49,10 +49,10 @@ void SettingsDialog::initializeSettings() {
levelSpinBox->setValue(sliceView->GetLevel());
// Overlay opacity
- overlaySpinBox->setValue(sliceView->GetOverlayOpacity());
+ overlayOpacitySpinBox->setValue(sliceView->GetOverlayOpacity());
- // Region opacity
- opacitySpinBox->setValue(volumeView->GetVisibleOpacity());
+ // Surface opacity
+ surfaceOpacitySpinBox->setValue(volumeView->GetVisibleOpacity());
}
void SettingsDialog::on_windowSpinBox_valueChanged(double value) {
@@ -63,28 +63,28 @@ void SettingsDialog::on_levelSpinBox_valueChanged(double value) {
visualizationContainer->GetSliceView()->SetLevel(value);
}
-void SettingsDialog::on_overlaySpinBox_valueChanged(double value) {
+void SettingsDialog::on_overlayOpacitySpinBox_valueChanged(double value) {
visualizationContainer->GetSliceView()->SetOverlayOpacity(value);
}
-void SettingsDialog::on_overlayUp() {
- overlaySpinBox->stepUp();
+void SettingsDialog::on_overlayOpacityUp() {
+ overlayOpacitySpinBox->stepUp();
}
-void SettingsDialog::on_overlayDown() {
- overlaySpinBox->stepDown();
+void SettingsDialog::on_overlayOpacityDown() {
+ overlayOpacitySpinBox->stepDown();
}
-void SettingsDialog::on_opacitySpinBox_valueChanged(double value) {
+void SettingsDialog::on_surfaceOpacitySpinBox_valueChanged(double value) {
visualizationContainer->SetVisibleOpacity(value);
}
-void SettingsDialog::on_opacityUp() {
- opacitySpinBox->stepUp();
+void SettingsDialog::on_surfaceOpacityUp() {
+ surfaceOpacitySpinBox->stepUp();
}
-void SettingsDialog::on_opacityDown() {
- opacitySpinBox->stepDown();
+void SettingsDialog::on_surfaceOpacityDown() {
+ surfaceOpacitySpinBox->stepDown();
}
void SettingsDialog::on_voxelSizeSpinBox() {
@@ -100,10 +100,18 @@ void SettingsDialog::on_windowLevelChanged(double window, double level) {
levelSpinBox->setValue(level);
}
-void SettingsDialog::on_overlayChanged(double value) {
- overlaySpinBox->setValue(value);
+void SettingsDialog::on_overlayOpacityChanged(double value) {
+ overlayOpacitySpinBox->setValue(value);
}
-void SettingsDialog::on_opacityChanged(double value) {
- opacitySpinBox->setValue(value);
+void SettingsDialog::on_surfaceOpacityChanged(double value) {
+ surfaceOpacitySpinBox->setValue(value);
+}
+
+void SettingsDialog::on_gradientOpacityCheckBox_stateChanged(int state) {
+ visualizationContainer->GetVolumeView()->SetVolumeRenderingGradientOpacity(state != 0);
+}
+
+void SettingsDialog::on_autoAdjustSamplingCheckBox_stateChanged(int state) {
+ visualizationContainer->GetVolumeView()->SetVolumeRenderingAutoAdjustSampling(state != 0);
}
\ No newline at end of file
diff --git a/qt/SettingsDialog.h b/qt/SettingsDialog.h
index 005dec6..396fa18 100644
--- a/qt/SettingsDialog.h
+++ b/qt/SettingsDialog.h
@@ -23,19 +23,22 @@ public slots:
virtual void on_windowSpinBox_valueChanged(double value);
virtual void on_levelSpinBox_valueChanged(double value);
- virtual void on_overlaySpinBox_valueChanged(double value);
- virtual void on_overlayUp();
- virtual void on_overlayDown();
+ virtual void on_overlayOpacitySpinBox_valueChanged(double value);
+ virtual void on_overlayOpacityUp();
+ virtual void on_overlayOpacityDown();
- virtual void on_opacitySpinBox_valueChanged(double value);
- virtual void on_opacityUp();
- virtual void on_opacityDown();
+ virtual void on_surfaceOpacitySpinBox_valueChanged(double value);
+ virtual void on_surfaceOpacityUp();
+ virtual void on_surfaceOpacityDown();
virtual void on_voxelSizeSpinBox();
virtual void on_windowLevelChanged(double window, double level);
- virtual void on_overlayChanged(double value);
- virtual void on_opacityChanged(double value);
+ virtual void on_overlayOpacityChanged(double value);
+ virtual void on_surfaceOpacityChanged(double value);
+
+ virtual void on_gradientOpacityCheckBox_stateChanged(int state);
+ virtual void on_autoAdjustSamplingCheckBox_stateChanged(int state);
protected:
VisualizationContainer* visualizationContainer;
diff --git a/qt/SettingsDialog.ui b/qt/SettingsDialog.ui
index 535d540..3fa258e 100644
--- a/qt/SettingsDialog.ui
+++ b/qt/SettingsDialog.ui
@@ -7,7 +7,7 @@
0
0
314
- 251
+ 367
@@ -199,96 +199,136 @@
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Overlay opacity (Left / right arrow)
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- 2
-
-
- 0.000000000000000
-
-
- 1.000000000000000
-
-
- 0.050000000000000
-
-
- 0.100000000000000
-
-
-
-
+
+
+ Region opacity
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Overlay (Left / right arrow)
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 2
+
+
+ 0.000000000000000
+
+
+ 1.000000000000000
+
+
+ 0.050000000000000
+
+
+ 0.100000000000000
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Surface (Shift + left / right arrow)
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+ 0.050000000000000
+
+
+ 1.000000000000000
+
+
+
+
+
+
+
-
-
-
-
-
-
-
- 0
- 0
-
-
-
- Region opacity (Shift + left / right arrow)
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- 1.000000000000000
-
-
- 0.050000000000000
-
-
- 1.000000000000000
-
-
-
-
+
+
+ Volume rendering
+
+
+ -
+
+
-
+
+
+ Gradient opacity (\)
+
+
+
+
+
+ -
+
+
-
+
+
+ Auto adjust sampling
+
+
+
+
+
+
+
-
diff --git a/visualization/VolumeView.cxx b/visualization/VolumeView.cxx
index bc79399..c151789 100644
--- a/visualization/VolumeView.cxx
+++ b/visualization/VolumeView.cxx
@@ -7,7 +7,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -24,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -447,11 +447,35 @@ void VolumeView::UpdateVolumeMask(bool filter) {
}
}
+void VolumeView::SetVolumeRenderingGradientOpacity(bool gradientOpacity) {
+ volume->GetProperty()->SetDisableGradientOpacity(!gradientOpacity);
+
+ Render();
+}
+
+bool VolumeView::GetVolumeRenderingGradientOpacity() {
+ return !volume->GetProperty()->GetDisableGradientOpacity();
+}
+
+void VolumeView::SetVolumeRenderingAutoAdjustSampling(bool autoAdjust) {
+ volumeMapper->SetAutoAdjustSampleDistances(autoAdjust);
+ volumeMapper->SetInteractiveAdjustSampleDistances(autoAdjust);
+}
+
void VolumeView::UpdateVolumeRenderingTransferFunctions(double x1, double x2) {
+ vtkPiecewiseFunction* opacity = volume->GetProperty()->GetScalarOpacity();
+ vtkPiecewiseFunction* gradientOpacity = volume->GetProperty()->GetStoredGradientOpacity();
+ vtkColorTransferFunction* color = volume->GetProperty()->GetRGBTransferFunction();
+
// Opacity
- volumeOpacity->RemoveAllPoints();
- volumeOpacity->AddPoint(x1, 0.0);
- volumeOpacity->AddPoint(x2, 0.5);
+ opacity->RemoveAllPoints();
+ opacity->AddPoint(x1, 0.0);
+ opacity->AddPoint(x2, 0.5);
+
+ // Gradient opacity
+ gradientOpacity->RemoveAllPoints();
+ gradientOpacity->AddPoint(0, 0.0);
+ gradientOpacity->AddPoint((x2 - x1) / 2, 1.0);
// Colors
// Paraview diverging
@@ -468,10 +492,10 @@ void VolumeView::UpdateVolumeRenderingTransferFunctions(double x1, double x2) {
}
}
- volumeColor->RemoveAllPoints();
+ color->RemoveAllPoints();
for (int i = 0; i < numColors; i++) {
double x = x1 + (double)i / (numColors - 1) * (x2 - x1);
- volumeColor->AddRGBPoint(x, colors[i][0], colors[i][1], colors[i][2]);
+ color->AddRGBPoint(x, colors[i][0], colors[i][1], colors[i][2]);
}
}
@@ -505,23 +529,24 @@ void VolumeView::CreateVolumeRenderer() {
volumeMask = vtkSmartPointer::New();
volumeMask->SetMaskInputData(volumeCopy->GetOutput());
- volumeMapper = vtkSmartPointer::New();
+ volumeMapper = vtkSmartPointer::New();
volumeMapper->SetBlendModeToComposite();
volumeMapper->AutoAdjustSampleDistancesOn();
volumeMapper->SetSampleDistance(0.1);
- volumeMapper->SetInteractiveSampleDistance(0.1);
- volumeMapper->SetImageSampleDistance(0.5);
- volumeMapper->SetMaximumImageSampleDistance(2);
+ volumeMapper->SetAutoAdjustSampleDistances(false);
+ volumeMapper->SetInteractiveAdjustSampleDistances(false);
- volumeOpacity = vtkSmartPointer::New();
-
- volumeColor = vtkSmartPointer::New();
+ vtkSmartPointer opacity = vtkSmartPointer::New();
+ vtkSmartPointer gradientOpacity = vtkSmartPointer::New();
+ vtkSmartPointer color = vtkSmartPointer::New();
vtkSmartPointer volumeProperty = vtkSmartPointer::New();
volumeProperty->ShadeOff();
volumeProperty->SetInterpolationTypeToLinear();
- volumeProperty->SetScalarOpacity(volumeOpacity);
- volumeProperty->SetColor(volumeColor);
+ volumeProperty->SetScalarOpacity(opacity);
+ volumeProperty->SetGradientOpacity(gradientOpacity);
+ volumeProperty->SetDisableGradientOpacity(true);
+ volumeProperty->SetColor(color);
volume = vtkSmartPointer::New();
volume->SetMapper(volumeMapper);
diff --git a/visualization/VolumeView.h b/visualization/VolumeView.h
index c6ce198..ba119e7 100644
--- a/visualization/VolumeView.h
+++ b/visualization/VolumeView.h
@@ -16,14 +16,14 @@ class vtkImageData;
class vtkLookupTable;
class vtkImageMapToColors;
class vtkImageMask;
-class vtkFixedPointVolumeRayCastMapper;
class vtkPiecewiseFunction;
class vtkPlaneSource;
class vtkObject;
class vtkOutlineCornerFilter;
class vtkPassThrough;
class vtkRenderer;
-class vtkRenderWindowInteractor;
+class vtkRenderWindowInteractor;
+class vtkSmartVolumeMapper;
class vtkTextActor;
class vtkVolume;
@@ -83,9 +83,13 @@ class VolumeView {
void SetBrushRadius(int radius);
+ // Volume rendering
void SetWindowLevel(double window, double level);
-
void UpdateVolumeMask(bool filter);
+ void SetVolumeRenderingGradientOpacity(bool gradientOpacity);
+ bool GetVolumeRenderingGradientOpacity();
+ void SetVolumeRenderingAutoAdjustSampling(bool autoAdjust);
+ bool GetVolumeRenderingAutoAdjustSampling();
void Render();
@@ -142,10 +146,8 @@ class VolumeView {
// Volume rendering
vtkSmartPointer volumeCopy;
vtkSmartPointer volumeMask;
- vtkSmartPointer volumeMapper;
+ vtkSmartPointer volumeMapper;
vtkSmartPointer volume;
- vtkSmartPointer volumeOpacity;
- vtkSmartPointer volumeColor;
void CreateVolumeRenderer();
void UpdateVolumeRenderer();
void UpdateVolumeRenderingTransferFunctions(double x1, double x2);