From ba2af5797ebe431b142faa901b62a4f042a2fd1e Mon Sep 17 00:00:00 2001 From: David Borland Date: Thu, 12 Dec 2019 16:32:29 -0500 Subject: [PATCH] Add toolbar to control some visualization settings --- CMakeLists.txt | 6 +- MainWindow.cxx | 65 +++++++- MainWindow.h | 5 + Segmentor.qrc | 9 + SliceView.cxx | 36 ++-- SliceView.h | 4 + VisualizationContainer.cxx | 4 + VisualizationContainer.h | 1 + VolumeView.cxx | 8 + VolumeView.h | 2 + icons/icon_outline.svg | 135 +++++++++++++++ icons/icon_overlay.svg | 144 ++++++++++++++++ icons/icon_smooth_normals.svg | 302 ++++++++++++++++++++++++++++++++++ icons/icon_smooth_surface.svg | 176 ++++++++++++++++++++ icons/icon_voxels.svg | 202 +++++++++++++++++++++++ 15 files changed, 1077 insertions(+), 22 deletions(-) create mode 100644 Segmentor.qrc create mode 100644 icons/icon_outline.svg create mode 100644 icons/icon_overlay.svg create mode 100644 icons/icon_smooth_normals.svg create mode 100644 icons/icon_smooth_surface.svg create mode 100644 icons/icon_voxels.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index 5220646..9b76733 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ include(${VTK_USE_FILE}) if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION VERSION_GREATER "4") # Instruct CMake to run moc automatically when needed. set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTORCC ON) find_package(Qt5Widgets REQUIRED QUIET) else() find_package(Qt4 REQUIRED) @@ -27,14 +28,13 @@ file(GLOB CXX_FILES *.cxx) if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION VERSION_GREATER "4") qt5_wrap_ui(UISrcs ${UI_FILES} ) # CMAKE_AUTOMOC in ON so the MOC headers will be automatically wrapped. - add_executable(Segmentor MACOSX_BUNDLE - ${CXX_FILES} ${UISrcs} ${QT_WRAP}) + add_executable(Segmentor MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${QT_WRAP} Segmentor.qrc) qt5_use_modules(Segmentor Core Gui) target_link_libraries(Segmentor ${VTK_LIBRARIES}) else() QT4_WRAP_UI(UISrcs ${UI_FILES}) QT4_WRAP_CPP(MOCSrcs ${QT_WRAP}) - add_executable(Segmentor MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${MOCSrcs}) + add_executable(Segmentor MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${MOCSrcs} Segmentor.qrc) target_link_libraries(Segmentor ${VTK_LIBRARIES}) endif() diff --git a/MainWindow.cxx b/MainWindow.cxx index 93595ea..7c71db5 100644 --- a/MainWindow.cxx +++ b/MainWindow.cxx @@ -15,6 +15,8 @@ #include "RegionTable.h" #include "RegionMetadataIO.h" #include "InteractionEnums.h" +#include "SliceView.h" +#include "VolumeView.h" #include "vtkCallbackCommand.h" #include "vtkSmartPointer.h" @@ -29,9 +31,6 @@ MainWindow::MainWindow() { defaultImageDirectoryKey = "default_image_directory"; defaultSegmentationDirectoryKey = "default_segmentation_directory"; - // Create tool bar - CreateToolBar(); - // Create render windows vtkNew renderWindowLeft; qvtkWidgetLeft->SetRenderWindow(renderWindowLeft); @@ -42,6 +41,9 @@ MainWindow::MainWindow() { // Create visualization container visualizationContainer = new VisualizationContainer(qvtkWidgetLeft->GetInteractor(), qvtkWidgetRight->GetInteractor(), this); + // Create tool bar + CreateToolBar(); + // Create region table regionTable = new RegionTable(); regionTable->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); @@ -321,7 +323,6 @@ void MainWindow::on_actionExit_triggered() { } void MainWindow::on_actionNavigation() { - visualizationContainer->SetInteractionMode(NavigationMode); } @@ -329,6 +330,26 @@ void MainWindow::on_actionEdit() { visualizationContainer->SetInteractionMode(EditMode); } +void MainWindow::on_actionOverlay(bool checked) { + visualizationContainer->GetSliceView()->ShowLabelSlice(checked); +} + +void MainWindow::on_actionVoxels(bool checked) { + visualizationContainer->GetSliceView()->ShowVoxelOutlines(checked); +} + +void MainWindow::on_actionOutline(bool checked) { + visualizationContainer->GetSliceView()->ShowRegionOutlines(checked); +} + +void MainWindow::on_actionSmoothNormals(bool checked) { + visualizationContainer->GetVolumeView()->SetSmoothShading(checked); +} + +void MainWindow::on_actionSmoothSurfaces(bool checked) { + visualizationContainer->GetVolumeView()->SetSmoothSurfaces(checked); +} + void MainWindow::on_regionDone(int label, bool done) { visualizationContainer->SetRegionDone((unsigned short)label, done); } @@ -377,16 +398,48 @@ void MainWindow::CreateToolBar() { QAction* actionNavigation = new QAction("N", interactionModeGroup); actionNavigation->setCheckable(true); - actionNavigation->setChecked(true); + actionNavigation->setChecked(visualizationContainer->GetInteractionMode() == NavigationMode); QAction* actionEdit = new QAction("E", interactionModeGroup); - actionNavigation->setCheckable(false); + actionEdit->setCheckable(true); + + QAction* actionOverlay = new QAction(QIcon(":/icons/icon_overlay.svg"), "Show overlay", this); + actionOverlay->setCheckable(true); + actionOverlay->setChecked(visualizationContainer->GetSliceView()->GetShowLabelSlice()); + + QAction* actionVoxels = new QAction(QIcon(":/icons/icon_voxels.svg"), "Show voxels", this); + actionVoxels->setCheckable(true); + actionVoxels->setChecked(visualizationContainer->GetSliceView()->GetShowVoxelOutlines()); + + QAction* actionOutline = new QAction(QIcon(":/icons/icon_outline.svg"), "Show outlines", this); + actionOutline->setCheckable(true); + actionOutline->setChecked(visualizationContainer->GetSliceView()->GetShowRegionOutlines()); + + QAction* actionSmoothNormals = new QAction(QIcon(":/icons/icon_smooth_normals.svg"), "Smooth normals", this); + actionSmoothNormals->setCheckable(true); + actionSmoothNormals->setChecked(visualizationContainer->GetVolumeView()->GetSmoothShading()); + + QAction* actionSmoothSurfaces = new QAction(QIcon(":/icons/icon_smooth_surface.svg"), "Smooth surfaces", this); + actionSmoothSurfaces->setCheckable(true); + actionSmoothSurfaces->setChecked(visualizationContainer->GetVolumeView()->GetSmoothSurfaces()); toolBar->addAction(actionNavigation); toolBar->addAction(actionEdit); + toolBar->addSeparator(); + toolBar->addAction(actionOverlay); + toolBar->addAction(actionVoxels); + toolBar->addAction(actionOutline); + toolBar->addSeparator(); + toolBar->addAction(actionSmoothNormals); + toolBar->addAction(actionSmoothSurfaces); QObject::connect(actionNavigation, &QAction::triggered, this, &MainWindow::on_actionNavigation); QObject::connect(actionEdit, &QAction::triggered, this, &MainWindow::on_actionEdit); + QObject::connect(actionOverlay, &QAction::triggered, this, &MainWindow::on_actionOverlay); + QObject::connect(actionVoxels, &QAction::triggered, this, &MainWindow::on_actionVoxels); + QObject::connect(actionOutline, &QAction::triggered, this, &MainWindow::on_actionOutline); + QObject::connect(actionSmoothNormals, &QAction::triggered, this, &MainWindow::on_actionSmoothNormals); + QObject::connect(actionSmoothSurfaces, &QAction::triggered, this, &MainWindow::on_actionSmoothSurfaces); toolBarWidget->layout()->addWidget(toolBar); } \ No newline at end of file diff --git a/MainWindow.h b/MainWindow.h index 7f9c26a..26cc00b 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -46,6 +46,11 @@ public slots: // Tool bar events virtual void on_actionNavigation(); virtual void on_actionEdit(); + virtual void on_actionOverlay(bool checked); + virtual void on_actionVoxels(bool checked); + virtual void on_actionOutline(bool checked); + virtual void on_actionSmoothNormals(bool checked); + virtual void on_actionSmoothSurfaces(bool checked); // Region table events virtual void on_regionDone(int label, bool done); diff --git a/Segmentor.qrc b/Segmentor.qrc new file mode 100644 index 0000000..e5ff64c --- /dev/null +++ b/Segmentor.qrc @@ -0,0 +1,9 @@ + + + icons/icon_overlay.svg + icons/icon_voxels.svg + icons/icon_outline.svg + icons/icon_smooth_surface.svg + icons/icon_smooth_normals.svg + + \ No newline at end of file diff --git a/SliceView.cxx b/SliceView.cxx index 8241fc6..c8b7e3b 100644 --- a/SliceView.cxx +++ b/SliceView.cxx @@ -53,7 +53,6 @@ SliceView::SliceView(vtkRenderWindowInteractor* interactor, vtkLookupTable* lut) plane = vtkSmartPointer::New(); labelSlice = vtkSmartPointer::New(); - labelSlice->VisibilityOn(); // Rendering renderer = vtkSmartPointer::New(); @@ -122,8 +121,8 @@ void SliceView::Reset() { SetCurrentRegion(nullptr); - slice->VisibilityOff(); - labelSlice->VisibilityOff(); + //slice->VisibilityOff(); + //labelSlice->VisibilityOff(); probe->VisibilityOff(); sliceLocation->UpdateData(nullptr); interactionModeLabel->VisibilityOff(); @@ -222,11 +221,24 @@ void SliceView::SetInteractionMode(enum InteractionMode mode) { style->SetMode(mode); } -void SliceView::ToggleLabelSlice() { - labelSlice->SetVisibility(!labelSlice->GetVisibility()); +bool SliceView::GetShowLabelSlice() { + return labelSlice->GetVisibility(); +} + +void SliceView::ShowLabelSlice(bool show) { + labelSlice->SetVisibility(show); + Render(); } +void SliceView::ToggleLabelSlice() { + ShowLabelSlice(!labelSlice->GetVisibility()); +} + +bool SliceView::GetShowVoxelOutlines() { + return showVoxelOutlines; +} + void SliceView::ShowVoxelOutlines(bool show) { showVoxelOutlines = show; @@ -239,6 +251,10 @@ void SliceView::ToggleVoxelOutlines() { ShowVoxelOutlines(!showVoxelOutlines); } +bool SliceView::GetShowRegionOutlines() { + return showRegionOutlines; +} + void SliceView::ShowRegionOutlines(bool show) { showRegionOutlines = show; @@ -334,9 +350,6 @@ void SliceView::CreateSlice() { slice = vtkSmartPointer::New(); slice->SetMapper(mapper); slice->SetProperty(property); - slice->VisibilityOff(); - - renderer->AddActor(slice); } void SliceView::UpdateSlice() { @@ -348,7 +361,7 @@ void SliceView::UpdateSlice() { slice->GetProperty()->SetColorWindow(maxValue - minValue); slice->GetProperty()->SetColorLevel(minValue + (maxValue - minValue) / 2); - slice->VisibilityOn(); + renderer->AddActor(slice); } void SliceView::CreateLabelSlice() { @@ -372,15 +385,12 @@ void SliceView::CreateLabelSlice() { // Slice labelSlice->SetMapper(mapper); labelSlice->SetProperty(property); - labelSlice->VisibilityOff(); - - labelSliceRenderer->AddActor(labelSlice); } void SliceView::UpdateLabelSlice() { labelSlice->GetMapper()->SetInputDataObject(labels); - labelSlice->VisibilityOn(); + labelSliceRenderer->AddActor(labelSlice); } void SliceView::FilterRegions() { diff --git a/SliceView.h b/SliceView.h index 1a083da..afcb500 100644 --- a/SliceView.h +++ b/SliceView.h @@ -40,11 +40,15 @@ class SliceView { void SetCurrentRegion(Region* region); + bool GetShowLabelSlice(); + void ShowLabelSlice(bool show); void ToggleLabelSlice(); + bool GetShowVoxelOutlines(); void ShowVoxelOutlines(bool show); void ToggleVoxelOutlines(); + bool GetShowRegionOutlines(); void ShowRegionOutlines(bool show); void ToggleRegionOutlines(); diff --git a/VisualizationContainer.cxx b/VisualizationContainer.cxx index 3e65ff6..2bb7526 100644 --- a/VisualizationContainer.cxx +++ b/VisualizationContainer.cxx @@ -343,6 +343,10 @@ void VisualizationContainer::SegmentVolume() { Render(); } +InteractionMode VisualizationContainer::GetInteractionMode() { + return interactionMode; +} + void VisualizationContainer::SetInteractionMode(InteractionMode mode) { interactionMode = mode; diff --git a/VisualizationContainer.h b/VisualizationContainer.h index 46f472b..8655081 100644 --- a/VisualizationContainer.h +++ b/VisualizationContainer.h @@ -43,6 +43,7 @@ class VisualizationContainer { void SegmentVolume(); FileErrorCode SaveSegmentationData(const std::string& fileName); + InteractionMode GetInteractionMode(); void SetInteractionMode(InteractionMode mode); void ToggleInteractionMode(); diff --git a/VolumeView.cxx b/VolumeView.cxx index b14e4be..c4646b5 100644 --- a/VolumeView.cxx +++ b/VolumeView.cxx @@ -159,6 +159,10 @@ void VolumeView::SetInteractionMode(enum InteractionMode mode) { style->SetMode(mode); } +bool VolumeView::GetSmoothSurfaces() { + return smoothSurfaces; +} + void VolumeView::SetSmoothSurfaces(bool smooth) { smoothSurfaces = smooth; @@ -173,6 +177,10 @@ void VolumeView::ToggleSmoothSurfaces() { SetSmoothSurfaces(!smoothSurfaces); } +bool VolumeView::GetSmoothShading() { + return smoothShading; +} + void VolumeView::SetSmoothShading(bool smooth) { smoothShading = smooth; diff --git a/VolumeView.h b/VolumeView.h index ff4fd69..e58b485 100644 --- a/VolumeView.h +++ b/VolumeView.h @@ -40,9 +40,11 @@ class VolumeView { void SetCurrentRegion(Region* region); + bool GetSmoothSurfaces(); void SetSmoothSurfaces(bool smooth); void ToggleSmoothSurfaces(); + bool GetSmoothShading(); void SetSmoothShading(bool smooth); void ToggleSmoothShading(); diff --git a/icons/icon_outline.svg b/icons/icon_outline.svg new file mode 100644 index 0000000..45b8ec0 --- /dev/null +++ b/icons/icon_outline.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/icon_overlay.svg b/icons/icon_overlay.svg new file mode 100644 index 0000000..9766886 --- /dev/null +++ b/icons/icon_overlay.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/icon_smooth_normals.svg b/icons/icon_smooth_normals.svg new file mode 100644 index 0000000..37317ba --- /dev/null +++ b/icons/icon_smooth_normals.svg @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/icons/icon_smooth_surface.svg b/icons/icon_smooth_surface.svg new file mode 100644 index 0000000..ed06e4b --- /dev/null +++ b/icons/icon_smooth_surface.svg @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/icons/icon_voxels.svg b/icons/icon_voxels.svg new file mode 100644 index 0000000..e519329 --- /dev/null +++ b/icons/icon_voxels.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + +