diff --git a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp deleted file mode 100644 index 135bcb9362..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "QmitkSurfaceBasedInterpolatorWidget.h" - -#include "mitkColorProperty.h" -#include "mitkInteractionConst.h" -#include "mitkOperationEvent.h" -#include "mitkProgressBar.h" -#include "mitkProperties.h" -#include "mitkRenderingManager.h" -#include "mitkSegTool2D.h" -#include "mitkSliceNavigationController.h" -#include "mitkSurfaceToImageFilter.h" -#include "mitkUndoController.h" -#include "mitkVtkRepresentationProperty.h" -#include - -#include -#include - -#include - -QmitkSurfaceBasedInterpolatorWidget::QmitkSurfaceBasedInterpolatorWidget(QWidget *parent, const char * /*name*/) - : QWidget(parent), - m_SurfaceBasedInterpolatorController(mitk::SurfaceBasedInterpolationController::GetInstance()), - m_ToolManager(nullptr), - m_Activated(false), - m_DataStorage(nullptr) -{ - m_Controls.setupUi(this); - - m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); - - m_ToolManager->WorkingDataChanged += mitk::MessageDelegate( - this, &QmitkSurfaceBasedInterpolatorWidget::OnToolManagerWorkingDataModified); - - connect(m_Controls.m_btStart, SIGNAL(toggled(bool)), this, SLOT(OnToggleWidgetActivation(bool))); - connect(m_Controls.m_btAccept, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked())); - connect(m_Controls.m_cbShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool))); - - itk::ReceptorMemberCommand::Pointer command = - itk::ReceptorMemberCommand::New(); - command->SetCallbackFunction(this, &QmitkSurfaceBasedInterpolatorWidget::OnSurfaceInterpolationInfoChanged); - m_SurfaceInterpolationInfoChangedObserverTag = - m_SurfaceBasedInterpolatorController->AddObserver(itk::ModifiedEvent(), command); - - m_InterpolatedSurfaceNode = mitk::DataNode::New(); - m_InterpolatedSurfaceNode->SetName("Surface Interpolation feedback"); - m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0)); - m_InterpolatedSurfaceNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); - m_InterpolatedSurfaceNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); - m_InterpolatedSurfaceNode->SetProperty("helper object", mitk::BoolProperty::New(true)); - m_InterpolatedSurfaceNode->SetVisibility(false); - - m_3DContourNode = mitk::DataNode::New(); - m_3DContourNode->SetName("Drawn Contours"); - m_3DContourNode->SetProperty("color", mitk::ColorProperty::New(0.0, 0.0, 0.0)); - m_3DContourNode->SetProperty("helper object", mitk::BoolProperty::New(true)); - m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME)); - m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f)); - m_3DContourNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); - m_3DContourNode->SetVisibility(false); - connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer())); - connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished())); - connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer())); - - m_Timer = new QTimer(this); - connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor())); - - m_Controls.m_btAccept->setEnabled(false); - m_Controls.m_cbShowPositionNodes->setEnabled(false); - - this->setEnabled(false); -} - -void QmitkSurfaceBasedInterpolatorWidget::SetDataStorage(mitk::DataStorage &storage) -{ - m_DataStorage = &storage; -} - -QmitkSurfaceBasedInterpolatorWidget::~QmitkSurfaceBasedInterpolatorWidget() -{ - m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate( - this, &QmitkSurfaceBasedInterpolatorWidget::OnToolManagerWorkingDataModified); - - if (m_DataStorage->Exists(m_3DContourNode)) - m_DataStorage->Remove(m_3DContourNode); - - if (m_DataStorage->Exists(m_InterpolatedSurfaceNode)) - m_DataStorage->Remove(m_InterpolatedSurfaceNode); - - // remove observer - m_SurfaceBasedInterpolatorController->RemoveObserver(m_SurfaceInterpolationInfoChangedObserverTag); - - delete m_Timer; -} - -void QmitkSurfaceBasedInterpolatorWidget::ShowInterpolationResult(bool status) -{ - if (m_InterpolatedSurfaceNode.IsNotNull()) - m_InterpolatedSurfaceNode->SetVisibility(status); - - if (m_3DContourNode.IsNotNull()) - { - auto allRenderWindows = mitk::BaseRenderer::GetAll3DRenderWindows(); - for (auto mapit = allRenderWindows.begin(); mapit != allRenderWindows.end(); ++mapit) - { - m_3DContourNode->SetVisibility(status, mapit->second); - } - } - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkSurfaceBasedInterpolatorWidget::OnSurfaceInterpolationFinished() -{ - mitk::Surface::Pointer interpolatedSurface = m_SurfaceBasedInterpolatorController->GetInterpolationResult(); - - if (interpolatedSurface.IsNotNull()) - { - m_InterpolatedSurfaceNode->SetData(interpolatedSurface); - m_3DContourNode->SetData(m_SurfaceBasedInterpolatorController->GetContoursAsSurface()); - this->ShowInterpolationResult(true); - } - else - { - m_InterpolatedSurfaceNode->SetData(nullptr); - m_3DContourNode->SetData(nullptr); - this->ShowInterpolationResult(false); - } -} - -void QmitkSurfaceBasedInterpolatorWidget::OnShowMarkers(bool state) -{ - mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = - m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true))); - - for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); - ++it) - { - it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state)); - } - - mitk::SegTool2D::Pointer manualSegmentationTool; - - unsigned int numberOfExistingTools = m_ToolManager->GetTools().size(); - - for (unsigned int i = 0; i < numberOfExistingTools; i++) - { - manualSegmentationTool = dynamic_cast(m_ToolManager->GetToolById(i)); - - if (manualSegmentationTool) - { - manualSegmentationTool->SetShowMarkerNodes(state); - } - } -} - -void QmitkSurfaceBasedInterpolatorWidget::StartUpdateInterpolationTimer() -{ - m_Timer->start(500); -} - -void QmitkSurfaceBasedInterpolatorWidget::StopUpdateInterpolationTimer() -{ - m_Timer->stop(); - m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 0.0)); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); -} - -void QmitkSurfaceBasedInterpolatorWidget::ChangeSurfaceColor() -{ - float currentColor[3]; - m_InterpolatedSurfaceNode->GetColor(currentColor); - - float yellow[3] = {255.0, 255.0, 0.0}; - - if (currentColor[2] == yellow[2]) - { - m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(255.0, 255.0, 255.0)); - } - else - { - m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(yellow)); - } - m_InterpolatedSurfaceNode->Update(); - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); -} - -void QmitkSurfaceBasedInterpolatorWidget::OnToolManagerWorkingDataModified() -{ - mitk::DataNode *workingNode = this->m_ToolManager->GetWorkingData(0); - if (!workingNode) - { - this->setEnabled(false); - return; - } - - mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData()); - // TODO adapt tool manager so that this check is done there, e.g. convenience function - // Q_ASSERT(workingImage); - if (!workingImage) - { - this->setEnabled(false); - return; - } - - if (workingImage->GetDimension() > 4 || workingImage->GetDimension() < 3) - { - this->setEnabled(false); - return; - } - - m_WorkingImage = workingImage; - - this->setEnabled(true); -} - -void QmitkSurfaceBasedInterpolatorWidget::OnRunInterpolation() -{ - m_SurfaceBasedInterpolatorController->Interpolate(); -} - -void QmitkSurfaceBasedInterpolatorWidget::OnToggleWidgetActivation(bool enabled) -{ - Q_ASSERT(m_ToolManager); - - mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); - if (!workingNode) - return; - - m_Controls.m_btAccept->setEnabled(enabled); - m_Controls.m_cbShowPositionNodes->setEnabled(enabled); - - if (enabled) - m_Controls.m_btStart->setText("Stop"); - else - m_Controls.m_btStart->setText("Start"); - - for (unsigned int i = 0; i < m_ToolManager->GetTools().size(); i++) - { - mitk::SegTool2D *tool = dynamic_cast(m_ToolManager->GetToolById(i)); - if (tool) - tool->SetEnable3DInterpolation(enabled); - } - - if (enabled) - { - if (!m_DataStorage->Exists(m_InterpolatedSurfaceNode)) - { - m_DataStorage->Add(m_InterpolatedSurfaceNode); - } - - if (!m_DataStorage->Exists(m_3DContourNode)) - { - m_DataStorage->Add(m_3DContourNode); - } - - mitk::Vector3D spacing = m_WorkingImage->GetGeometry(0)->GetSpacing(); - double minSpacing(100); - double maxSpacing(0); - for (int i = 0; i < 3; i++) - { - if (spacing[i] < minSpacing) - { - minSpacing = spacing[i]; - } - else if (spacing[i] > maxSpacing) - { - maxSpacing = spacing[i]; - } - } - - m_SurfaceBasedInterpolatorController->SetWorkingImage(m_WorkingImage); - m_SurfaceBasedInterpolatorController->SetActiveLabel(m_WorkingImage->GetActiveLabel()->GetValue()); - m_SurfaceBasedInterpolatorController->SetMaxSpacing(maxSpacing); - m_SurfaceBasedInterpolatorController->SetMinSpacing(minSpacing); - m_SurfaceBasedInterpolatorController->SetDistanceImageVolume(50000); - - int ret = QMessageBox::Yes; - - if (m_SurfaceBasedInterpolatorController->EstimatePortionOfNeededMemory() > 0.5) - { - QMessageBox msgBox; - msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!"); - msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?"); - msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); - ret = msgBox.exec(); - } - - if (m_Watcher.isRunning()) - m_Watcher.waitForFinished(); - - if (ret == QMessageBox::Yes) - { - m_Future = QtConcurrent::run(this, &QmitkSurfaceBasedInterpolatorWidget::OnRunInterpolation); - m_Watcher.setFuture(m_Future); - } - } - else - { - if (m_DataStorage->Exists(m_InterpolatedSurfaceNode)) - { - m_DataStorage->Remove(m_InterpolatedSurfaceNode); - } - if (m_DataStorage->Exists(m_3DContourNode)) - { - m_DataStorage->Remove(m_3DContourNode); - } - - mitk::UndoController::GetCurrentUndoModel()->Clear(); - } - - m_Activated = enabled; - - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); -} - -void QmitkSurfaceBasedInterpolatorWidget::OnAcceptInterpolationClicked() -{ - if (m_InterpolatedSurfaceNode.IsNotNull() && m_InterpolatedSurfaceNode->GetData()) - { - // m_WorkingImage->SurfaceStamp(dynamic_cast(m_InterpolatedSurfaceNode->GetData()), false); - this->ShowInterpolationResult(false); - } -} - -void QmitkSurfaceBasedInterpolatorWidget::OnSurfaceInterpolationInfoChanged(const itk::EventObject & /*e*/) -{ - if (m_Activated) - { - if (m_Watcher.isRunning()) - m_Watcher.waitForFinished(); - - m_Future = QtConcurrent::run(this, &QmitkSurfaceBasedInterpolatorWidget::OnRunInterpolation); - m_Watcher.setFuture(m_Future); - } -} diff --git a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.h b/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.h deleted file mode 100644 index a4582310dc..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidget.h +++ /dev/null @@ -1,119 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef QmitkSurfaceBasedInterpolatorWidgetWidget_h_Included -#define QmitkSurfaceBasedInterpolatorWidgetWidget_h_Included - -#include "MitkSegmentationUIExports.h" -#include "mitkDataNode.h" -#include "mitkDataStorage.h" -#include "mitkLabelSetImage.h" -#include "mitkSurfaceBasedInterpolationController.h" - -#include - -#include - -// For running 3D interpolation in background -#include -#include -#include -#include - -#include "ui_QmitkSurfaceBasedInterpolatorWidgetGUIControls.h" - -namespace mitk -{ - class ToolManager; -} - -/** - \brief GUI for surface-based interpolation. - - \ingroup ToolManagerEtAl - \ingroup Widgets - - \sa QmitkInteractiveSegmentation - \sa mitk::SurfaceBasedInterpolationController - - QmitkSurfaceBasedInterpolatorWidgetController is responsible to watch the GUI, to notice, which slice is currently - visible. It triggers generation of interpolation suggestions and also triggers acception of suggestions. -*/ -class MITKSEGMENTATIONUI_EXPORT QmitkSurfaceBasedInterpolatorWidget : public QWidget -{ - Q_OBJECT - -public: - QmitkSurfaceBasedInterpolatorWidget(QWidget *parent = nullptr, const char *name = nullptr); - ~QmitkSurfaceBasedInterpolatorWidget() override; - - void SetDataStorage(mitk::DataStorage &storage); - - void OnToolManagerWorkingDataModified(); - - /** - Just public because it is called by itk::Commands. You should not need to call this. - */ - void OnSurfaceInterpolationInfoChanged(const itk::EventObject &); - - /** - * @brief Set the visibility of the interpolation - */ - void ShowInterpolationResult(bool); - - Ui::QmitkSurfaceBasedInterpolatorWidgetGUIControls m_Controls; - -public slots: - - /** - \brief Reaction to "Start/Stop" button click - */ - void OnToggleWidgetActivation(bool); - -protected slots: - - void OnAcceptInterpolationClicked(); - - void OnSurfaceInterpolationFinished(); - - void OnRunInterpolation(); - - void OnShowMarkers(bool); - - void StartUpdateInterpolationTimer(); - - void StopUpdateInterpolationTimer(); - - void ChangeSurfaceColor(); - -private: - mitk::SurfaceBasedInterpolationController::Pointer m_SurfaceBasedInterpolatorController; - - mitk::ToolManager *m_ToolManager; - - bool m_Activated; - - unsigned int m_SurfaceInterpolationInfoChangedObserverTag; - - mitk::DataNode::Pointer m_InterpolatedSurfaceNode; - mitk::DataNode::Pointer m_3DContourNode; - - mitk::DataStorage::Pointer m_DataStorage; - - mitk::LabelSetImage::Pointer m_WorkingImage; - - QFuture m_Future; - QFutureWatcher m_Watcher; - QTimer *m_Timer; -}; - -#endif diff --git a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui b/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui deleted file mode 100644 index 7f639be5fb..0000000000 --- a/Modules/SegmentationUI/Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui +++ /dev/null @@ -1,136 +0,0 @@ - - - QmitkSurfaceBasedInterpolatorWidgetGUIControls - - - - 0 - 0 - 248 - 94 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Surface-Based Interpolation - - - - - - - 2 - - - QLayout::SetMinimumSize - - - 6 - - - - - 6 - - - - - true - - - - 0 - 0 - - - - Start/Stop the 3D interpolation utility - - - Start - - - - :/Qmitk/Start.png - :/Qmitk/Stop.png:/Qmitk/Start.png - - - - 32 - 32 - - - - true - - - false - - - Qt::ToolButtonTextUnderIcon - - - Qt::NoArrow - - - - - - - true - - - - 0 - 0 - - - - Accept - - - - :/Qmitk/AcceptSurfaceInterpolation.png:/Qmitk/AcceptSurfaceInterpolation.png - - - - 32 - 32 - - - - Qt::ToolButtonTextUnderIcon - - - - - - - - - true - - - show position nodes - - - - - - - - - - - diff --git a/Modules/SegmentationUI/files.cmake b/Modules/SegmentationUI/files.cmake index 08da87a365..113bbae7c7 100644 --- a/Modules/SegmentationUI/files.cmake +++ b/Modules/SegmentationUI/files.cmake @@ -1,102 +1,99 @@ set(CPP_FILES Qmitk/QmitkSegWithPreviewToolGUIBase.cpp Qmitk/QmitkMultiLabelSegWithPreviewToolGUIBase.cpp Qmitk/QmitkBinaryThresholdToolGUIBase.cpp Qmitk/QmitkBinaryThresholdToolGUI.cpp Qmitk/QmitkBinaryThresholdULToolGUI.cpp Qmitk/QmitkConfirmSegmentationDialog.cpp Qmitk/QmitkCopyToClipBoardDialog.cpp Qmitk/QmitkDrawPaintbrushToolGUI.cpp Qmitk/QmitkErasePaintbrushToolGUI.cpp Qmitk/QmitkEditableContourToolGUIBase.cpp Qmitk/QmitkGrowCutToolGUI.cpp Qmitk/QmitkLiveWireTool2DGUI.cpp Qmitk/QmitkLassoToolGUI.cpp Qmitk/QmitkOtsuTool3DGUI.cpp Qmitk/QmitkPaintbrushToolGUI.cpp Qmitk/QmitkPickingToolGUI.cpp Qmitk/QmitkSlicesInterpolator.cpp Qmitk/QmitkToolGUI.cpp Qmitk/QmitkToolGUIArea.cpp Qmitk/QmitkToolSelectionBox.cpp Qmitk/QmitknnUNetFolderParser.cpp Qmitk/QmitknnUNetToolGUI.cpp Qmitk/QmitknnUNetWorker.cpp Qmitk/QmitknnUNetGPU.cpp Qmitk/QmitkSurfaceStampWidget.cpp Qmitk/QmitkMaskStampWidget.cpp Qmitk/QmitkStaticDynamicSegmentationDialog.cpp - Qmitk/QmitkSurfaceBasedInterpolatorWidget.cpp Qmitk/QmitkSimpleLabelSetListWidget.cpp Qmitk/QmitkSegmentationTaskListWidget.cpp SegmentationUtilities/QmitkBooleanOperationsWidget.cpp SegmentationUtilities/QmitkContourModelToImageWidget.cpp SegmentationUtilities/QmitkImageMaskingWidget.cpp SegmentationUtilities/QmitkMorphologicalOperationsWidget.cpp SegmentationUtilities/QmitkSurfaceToImageWidget.cpp SegmentationUtilities/QmitkSegmentationUtilityWidget.cpp SegmentationUtilities/QmitkDataSelectionWidget.cpp ) set(MOC_H_FILES Qmitk/QmitkSegWithPreviewToolGUIBase.h Qmitk/QmitkMultiLabelSegWithPreviewToolGUIBase.h Qmitk/QmitkBinaryThresholdToolGUIBase.h Qmitk/QmitkBinaryThresholdToolGUI.h Qmitk/QmitkBinaryThresholdULToolGUI.h Qmitk/QmitkConfirmSegmentationDialog.h Qmitk/QmitkCopyToClipBoardDialog.h Qmitk/QmitkDrawPaintbrushToolGUI.h Qmitk/QmitkErasePaintbrushToolGUI.h Qmitk/QmitkEditableContourToolGUIBase.h Qmitk/QmitkGrowCutToolGUI.h Qmitk/QmitkLiveWireTool2DGUI.h Qmitk/QmitkLassoToolGUI.h Qmitk/QmitkOtsuTool3DGUI.h Qmitk/QmitkPaintbrushToolGUI.h Qmitk/QmitkPickingToolGUI.h Qmitk/QmitkSlicesInterpolator.h Qmitk/QmitkToolGUI.h Qmitk/QmitkToolGUIArea.h Qmitk/QmitkToolSelectionBox.h Qmitk/QmitknnUNetFolderParser.h Qmitk/QmitknnUNetToolGUI.h Qmitk/QmitknnUNetGPU.h Qmitk/QmitknnUNetWorker.h Qmitk/QmitknnUNetEnsembleLayout.h Qmitk/QmitkSurfaceStampWidget.h Qmitk/QmitkMaskStampWidget.h Qmitk/QmitkStaticDynamicSegmentationDialog.h - Qmitk/QmitkSurfaceBasedInterpolatorWidget.h Qmitk/QmitkSimpleLabelSetListWidget.h Qmitk/QmitkSegmentationTaskListWidget.h SegmentationUtilities/QmitkBooleanOperationsWidget.h SegmentationUtilities/QmitkContourModelToImageWidget.h SegmentationUtilities/QmitkImageMaskingWidget.h SegmentationUtilities/QmitkMorphologicalOperationsWidget.h SegmentationUtilities/QmitkSurfaceToImageWidget.h SegmentationUtilities/QmitkSegmentationUtilityWidget.h SegmentationUtilities/QmitkDataSelectionWidget.h ) set(UI_FILES Qmitk/QmitkConfirmSegmentationDialog.ui Qmitk/QmitkGrowCutToolWidgetControls.ui Qmitk/QmitkOtsuToolWidgetControls.ui Qmitk/QmitkSurfaceStampWidgetGUIControls.ui Qmitk/QmitkMaskStampWidgetGUIControls.ui - Qmitk/QmitkSurfaceBasedInterpolatorWidgetGUIControls.ui Qmitk/QmitknnUNetToolGUIControls.ui Qmitk/QmitkEditableContourToolGUIControls.ui Qmitk/QmitkSegmentationTaskListWidget.ui SegmentationUtilities/QmitkBooleanOperationsWidgetControls.ui SegmentationUtilities/QmitkContourModelToImageWidgetControls.ui SegmentationUtilities/QmitkImageMaskingWidgetControls.ui SegmentationUtilities/QmitkMorphologicalOperationsWidgetControls.ui SegmentationUtilities/QmitkSurfaceToImageWidgetControls.ui SegmentationUtilities/QmitkDataSelectionWidgetControls.ui ) set(QRC_FILES resources/SegmentationUI.qrc ) diff --git a/Modules/SegmentationUI/resources/AcceptAllInterpolations.png b/Modules/SegmentationUI/resources/AcceptAllInterpolations.png deleted file mode 100644 index 49f64408c1..0000000000 Binary files a/Modules/SegmentationUI/resources/AcceptAllInterpolations.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/AcceptCurrentInterpolation.png b/Modules/SegmentationUI/resources/AcceptCurrentInterpolation.png deleted file mode 100644 index f08c37c358..0000000000 Binary files a/Modules/SegmentationUI/resources/AcceptCurrentInterpolation.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/AcceptSurfaceInterpolation.png b/Modules/SegmentationUI/resources/AcceptSurfaceInterpolation.png deleted file mode 100644 index 71ac5e5ad8..0000000000 Binary files a/Modules/SegmentationUI/resources/AcceptSurfaceInterpolation.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/Accept_48x48.png b/Modules/SegmentationUI/resources/Accept_48x48.png deleted file mode 100644 index ba6fb3d55b..0000000000 Binary files a/Modules/SegmentationUI/resources/Accept_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/AdvancedTools.png b/Modules/SegmentationUI/resources/AdvancedTools.png deleted file mode 100644 index 18b22cb619..0000000000 Binary files a/Modules/SegmentationUI/resources/AdvancedTools.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/Cancel_48x48.png b/Modules/SegmentationUI/resources/Cancel_48x48.png deleted file mode 100644 index 6912aec695..0000000000 Binary files a/Modules/SegmentationUI/resources/Cancel_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/ClearSeeds_48x48.png b/Modules/SegmentationUI/resources/ClearSeeds_48x48.png deleted file mode 100644 index 0121c49d6c..0000000000 Binary files a/Modules/SegmentationUI/resources/ClearSeeds_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/Help_48x48.png b/Modules/SegmentationUI/resources/Help_48x48.png deleted file mode 100644 index d6b27b90e0..0000000000 Binary files a/Modules/SegmentationUI/resources/Help_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/ImportLabelSet_48x48.png b/Modules/SegmentationUI/resources/ImportLabelSet_48x48.png deleted file mode 100644 index 1903da38ac..0000000000 Binary files a/Modules/SegmentationUI/resources/ImportLabelSet_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/ImportLabeledImage_48x48.png b/Modules/SegmentationUI/resources/ImportLabeledImage_48x48.png deleted file mode 100644 index eda412a4b0..0000000000 Binary files a/Modules/SegmentationUI/resources/ImportLabeledImage_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/Run_48x48.png b/Modules/SegmentationUI/resources/Run_48x48.png deleted file mode 100644 index 9d32abe203..0000000000 Binary files a/Modules/SegmentationUI/resources/Run_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/SegmentationInteractor_48x48.png b/Modules/SegmentationUI/resources/SegmentationInteractor_48x48.png deleted file mode 100644 index a289c4a9e5..0000000000 Binary files a/Modules/SegmentationUI/resources/SegmentationInteractor_48x48.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/SegmentationUI.qrc b/Modules/SegmentationUI/resources/SegmentationUI.qrc index 6cb9f4894b..02157a1290 100644 --- a/Modules/SegmentationUI/resources/SegmentationUI.qrc +++ b/Modules/SegmentationUI/resources/SegmentationUI.qrc @@ -1,47 +1,33 @@ - AcceptCurrentInterpolation.png - AcceptAllInterpolations.png - AcceptSurfaceInterpolation.png BooleanDifference_48x48.png BooleanIntersection_48x48.png BooleanUnion_48x48.png BooleanLabelA_32x32.png BooleanLabelB_32x32.png Dilate_48x48.png Erode_48x48.png Closing_48x48.png Opening_48x48.png FillHoles_48x48.png - Accept_48x48.png - Cancel_48x48.png - Run_48x48.png - ImportLabelSet_48x48.png - ImportLabeledImage_48x48.png DeleteLayer_48x48.png PreviousLayer_48x48.png NextLayer_48x48.png AddLayer_48x48.png - SegmentationInteractor_48x48.png LockExterior_48x48.png UnlockExterior_48x48.png NewLabel_48x48.png NewSegmentation_48x48.png - ClearSeeds_48x48.png - Start.png - Stop.png - Help_48x48.png - AdvancedTools.png visible.svg invisible.svg lock.svg unlock.svg MergeLabels.png RemoveLabel.png EraseLabel.png CreateSurface.png CreateMask.png RandomColor.png RenameLabel.png diff --git a/Modules/SegmentationUI/resources/Start.png b/Modules/SegmentationUI/resources/Start.png deleted file mode 100644 index 6e8c0bb3c7..0000000000 Binary files a/Modules/SegmentationUI/resources/Start.png and /dev/null differ diff --git a/Modules/SegmentationUI/resources/Stop.png b/Modules/SegmentationUI/resources/Stop.png deleted file mode 100644 index 2d418b07ba..0000000000 Binary files a/Modules/SegmentationUI/resources/Stop.png and /dev/null differ diff --git a/Modules/SurfaceInterpolation/files.cmake b/Modules/SurfaceInterpolation/files.cmake index 7d2db9fb04..dcd61f705e 100644 --- a/Modules/SurfaceInterpolation/files.cmake +++ b/Modules/SurfaceInterpolation/files.cmake @@ -1,10 +1,9 @@ set(CPP_FILES mitkComputeContourSetNormalsFilter.cpp mitkCreateDistanceImageFromSurfaceFilter.cpp mitkImageToPointCloudFilter.cpp mitkPlaneProposer.cpp mitkPointCloudScoringFilter.cpp mitkReduceContourSetFilter.cpp mitkSurfaceInterpolationController.cpp - mitkSurfaceBasedInterpolationController.cpp ) diff --git a/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.cpp deleted file mode 100644 index dc2c2fa36c..0000000000 --- a/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#include "mitkSurfaceBasedInterpolationController.h" - -#include -#include "mitkComputeContourSetNormalsFilter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -mitk::SurfaceBasedInterpolationController::SurfaceBasedInterpolationController() - : m_MinSpacing(1.0), m_MaxSpacing(1.0), m_WorkingImage(nullptr), m_ActiveLabel(0) -{ - this->Initialize(); -} - -mitk::SurfaceBasedInterpolationController::~SurfaceBasedInterpolationController() -{ - auto it = m_MapOfContourLists.begin(); - for (; it != m_MapOfContourLists.end(); it++) - { - for (unsigned int j = 0; j < m_MapOfContourLists[(*it).first].size(); ++j) - { - delete (m_MapOfContourLists[(*it).first].at(j).second); - } - m_MapOfContourLists.erase(it); - } -} - -void mitk::SurfaceBasedInterpolationController::Initialize() -{ - m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New(); - m_InterpolateSurfaceFilter->SetUseProgressBar(false); - - m_Contours = Surface::New(); - - m_InterpolationResult = nullptr; -} - -mitk::SurfaceBasedInterpolationController *mitk::SurfaceBasedInterpolationController::GetInstance() -{ - static mitk::SurfaceBasedInterpolationController *m_Instance; - - if (m_Instance == nullptr) - { - m_Instance = new SurfaceBasedInterpolationController(); - } - - return m_Instance; -} - -void mitk::SurfaceBasedInterpolationController::AddNewContour(mitk::ContourModel::Pointer newContour, - RestorePlanePositionOperation *op) -{ - if (m_ActiveLabel == 0) - return; - - AffineTransform3D::Pointer transform = AffineTransform3D::New(); - transform = op->GetTransform(); - - mitk::Vector3D direction = op->GetDirectionVector(); - int pos = -1; - - for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++) - { - itk::Matrix diffM = - transform->GetMatrix() - m_MapOfContourLists[m_ActiveLabel].at(i).second->GetTransform()->GetMatrix(); - bool isSameMatrix(true); - for (unsigned int j = 0; j < 3; j++) - { - if (fabs(diffM[j][0]) > 0.0001 && fabs(diffM[j][1]) > 0.0001 && fabs(diffM[j][2]) > 0.0001) - { - isSameMatrix = false; - break; - } - } - itk::Vector diffV = - m_MapOfContourLists[m_ActiveLabel].at(i).second->GetTransform()->GetOffset() - transform->GetOffset(); - if (isSameMatrix && m_MapOfContourLists[m_ActiveLabel].at(i).second->GetPos() == op->GetPos() && - (fabs(diffV[0]) < 0.0001 && fabs(diffV[1]) < 0.0001 && fabs(diffV[2]) < 0.0001)) - { - pos = i; - break; - } - } - - if (pos == -1 && newContour->GetNumberOfVertices() > 0) // add a new contour - { - mitk::RestorePlanePositionOperation *newOp = new mitk::RestorePlanePositionOperation( - OpRESTOREPLANEPOSITION, op->GetWidth(), op->GetHeight(), op->GetSpacing(), op->GetPos(), direction, transform); - ContourPositionPair newData = std::make_pair(newContour, newOp); - m_MapOfContourLists[m_ActiveLabel].push_back(newData); - } - else if (pos != -1) // replace existing contour - { - m_MapOfContourLists[m_ActiveLabel].at(pos).first = newContour; - } - - this->Modified(); -} - -void mitk::SurfaceBasedInterpolationController::Interpolate() -{ - if (m_MapOfContourLists[m_ActiveLabel].size() < 2) - { - // If no interpolation is possible reset the interpolation result - m_InterpolationResult = nullptr; - return; - } - - m_InterpolateSurfaceFilter->Reset(); - - // MLI TODO - // m_InterpolateSurfaceFilter->SetReferenceImage( m_WorkingImage ); - - // CreateDistanceImageFromSurfaceFilter::Pointer interpolateSurfaceFilter = - // CreateDistanceImageFromSurfaceFilter::New(); - vtkSmartPointer polyDataAppender = vtkSmartPointer::New(); - - for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++) - { - mitk::ContourModelToSurfaceFilter::Pointer converter = mitk::ContourModelToSurfaceFilter::New(); - converter->SetInput(m_MapOfContourLists[m_ActiveLabel].at(i).first); - converter->Update(); - - mitk::Surface::Pointer surface = converter->GetOutput(); - surface->DisconnectPipeline(); - - ReduceContourSetFilter::Pointer reduceFilter = ReduceContourSetFilter::New(); - reduceFilter->SetUseProgressBar(false); - reduceFilter->SetInput(surface); - reduceFilter->SetMinSpacing(m_MinSpacing); - reduceFilter->SetMaxSpacing(m_MaxSpacing); - reduceFilter->Update(); - - ComputeContourSetNormalsFilter::Pointer normalsFilter = ComputeContourSetNormalsFilter::New(); - normalsFilter->SetUseProgressBar(false); - normalsFilter->SetInput(reduceFilter->GetOutput()); - normalsFilter->SetMaxSpacing(m_MaxSpacing); - // MLI TODO - // normalsFilter->SetSegmentationBinaryImage(m_WorkingImage, m_ActiveLabel); - // normalsFilter->Update(); - - m_InterpolateSurfaceFilter->SetInput(i, normalsFilter->GetOutput()); - - polyDataAppender->AddInputData(reduceFilter->GetOutput()->GetVtkPolyData()); - } - - polyDataAppender->Update(); - m_Contours->SetVtkPolyData(polyDataAppender->GetOutput()); - - // update the filter and get the resulting distance-image - m_InterpolateSurfaceFilter->Update(); - Image::Pointer distanceImage = m_InterpolateSurfaceFilter->GetOutput(); - if (distanceImage.IsNull()) - { - // If no interpolation is possible reset the interpolation result - m_InterpolationResult = nullptr; - return; - } - - // create a surface from the distance-image - mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New(); - imageToSurfaceFilter->SetInput(distanceImage); - imageToSurfaceFilter->SetThreshold(0); - imageToSurfaceFilter->SetSmooth(true); - imageToSurfaceFilter->SetSmoothIteration(20); - imageToSurfaceFilter->Update(); - m_InterpolationResult = imageToSurfaceFilter->GetOutput(); - - m_InterpolationResult->DisconnectPipeline(); -} - -mitk::Surface::Pointer mitk::SurfaceBasedInterpolationController::GetInterpolationResult() -{ - return m_InterpolationResult; -} - -mitk::Surface *mitk::SurfaceBasedInterpolationController::GetContoursAsSurface() -{ - return m_Contours; -} - -void mitk::SurfaceBasedInterpolationController::SetMinSpacing(double minSpacing) -{ - m_MinSpacing = minSpacing; -} - -void mitk::SurfaceBasedInterpolationController::SetMaxSpacing(double maxSpacing) -{ - m_MaxSpacing = maxSpacing; -} - -void mitk::SurfaceBasedInterpolationController::SetDistanceImageVolume(unsigned int value) -{ - m_DistanceImageVolume = value; -} - -void mitk::SurfaceBasedInterpolationController::SetWorkingImage(Image *workingImage) -{ - m_WorkingImage = workingImage; -} - -mitk::Image *mitk::SurfaceBasedInterpolationController::GetImage() -{ - return m_InterpolateSurfaceFilter->GetOutput(); -} - -double mitk::SurfaceBasedInterpolationController::EstimatePortionOfNeededMemory() -{ - double numberOfPoints = 0.0; - for (unsigned int i = 0; i < m_MapOfContourLists[m_ActiveLabel].size(); i++) - { - numberOfPoints += m_MapOfContourLists[m_ActiveLabel].at(i).first->GetNumberOfVertices() * 3; - } - - double sizeOfPoints = pow(numberOfPoints, 2) * sizeof(double); - double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); - double percentage = sizeOfPoints / totalMem; - return percentage; -} - -void mitk::SurfaceBasedInterpolationController::SetActiveLabel(int activeLabel) -{ - if (m_ActiveLabel == activeLabel) - return; - - if (activeLabel == 0) - return; - - m_ActiveLabel = activeLabel; - - auto it = m_MapOfContourLists.find(m_ActiveLabel); - - if (it == m_MapOfContourLists.end()) - { - ContourPositionPairList newList; - - m_MapOfContourLists[m_ActiveLabel] = newList; - - m_InterpolationResult = nullptr; - } - - this->Modified(); -} - -/* -void mitk::SurfaceBasedInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation) -{ - if (segmentation != 0) - { - m_MapOfContourLists.erase(segmentation); - if (m_SelectedSegmentation == segmentation) - { - SetSegmentationImage(nullptr); - m_SelectedSegmentation = 0; - } - } -} -*/ - -/* -void mitk::SurfaceBasedInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject -&event) -{ - mitk::Image* tempImage = dynamic_cast(const_cast(caller)); - if (tempImage) - { - RemoveSegmentationFromContourList(tempImage); - if (tempImage == m_SelectedSegmentation) - { - SetSegmentationImage(nullptr); - m_SelectedSegmentation = 0; - } - } -} -*/ diff --git a/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.h b/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.h deleted file mode 100644 index 4f7e70febb..0000000000 --- a/Modules/SurfaceInterpolation/mitkSurfaceBasedInterpolationController.h +++ /dev/null @@ -1,145 +0,0 @@ -/*============================================================================ - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center (DKFZ) -All rights reserved. - -Use of this source code is governed by a 3-clause BSD license that can be -found in the LICENSE file. - -============================================================================*/ - -#ifndef mitkSurfaceBasedInterpolationController_h_Included -#define mitkSurfaceBasedInterpolationController_h_Included - -//#include "mitkCommon.h" -#include "mitkContourModel.h" -#include -#include -#include - -#include "mitkCreateDistanceImageFromSurfaceFilter.h" -#include "mitkReduceContourSetFilter.h" - -#include - -namespace mitk -{ - class RestorePlanePositionOperation; - - class MITKSURFACEINTERPOLATION_EXPORT SurfaceBasedInterpolationController : public itk::Object - { - public: - mitkClassMacroItkParent(SurfaceBasedInterpolationController, itk::Object); - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); - - static SurfaceBasedInterpolationController *GetInstance(); - - /** - * Adds a new extracted contour to the list - */ - void AddNewContour(ContourModel::Pointer newContour, RestorePlanePositionOperation *op); - - /** - * Launches the interpolation method. A surface mesh is generated out of the given extracted contours. - */ - void Interpolate(); - - /** - * Retrieves a surface mesh resulting from the interpolation of the given extracted contours. - */ - mitk::Surface::Pointer GetInterpolationResult(); - - /** - * Sets the minimum spacing of the current selected segmentation - * This is needed since the contour points we reduced before, are used to interpolate the surface - */ - void SetMinSpacing(double minSpacing); - - /** - * Sets the minimum spacing of the current selected segmentation - * This is needed since the contour points we reduced before, are used to interpolate the surface - */ - void SetMaxSpacing(double maxSpacing); - - /** - * Sets the volume i.e. the number of pixels that the distance image should have - * By evaluation we found out that 50.000 pixel delivers a good result - */ - void SetDistanceImageVolume(unsigned int value); - - /** - * Sets the working image used by the interpolation method. - * This is needed because the calculation of the normals needs to now wheather a normal points toward the inside of - * a segmentation or not - */ - void SetWorkingImage(Image *workingImage); - - /** - * Retrieves the input contours as a mitk::Surface - */ - Surface *GetContoursAsSurface(); - - /** - * Sets the current list of contour points which is used for the surface interpolation - * @param activeLabel The active label in the current working image - */ - void SetActiveLabel(int activeLabel); - - mitk::Image *GetImage(); - - /** - * Estimates the memory that is needed to build up the equation system for the interpolation. - * \returns The percentage of the real memory which will be used by the interpolation calculation - */ - double EstimatePortionOfNeededMemory(); - - - protected: - SurfaceBasedInterpolationController(); - - ~SurfaceBasedInterpolationController() override; - - void Initialize(); - - private: - // void OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &event); - /* - struct ContourPositionPair { - ContourModel::Pointer contour; - RestorePlanePositionOperation* position; - }; - */ - typedef std::pair ContourPositionPair; - typedef std::vector ContourPositionPairList; - typedef std::map ContourListMap; - - // ReduceContourSetFilter::Pointer m_ReduceFilter; - // ComputeContourSetNormalsFilter::Pointer m_NormalsFilter; - CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter; - - double m_MinSpacing; - double m_MaxSpacing; - - unsigned int m_DistanceImageVolume; - - Image *m_WorkingImage; - - Surface::Pointer m_Contours; - - // vtkSmartPointer m_PolyData; - - ContourListMap m_MapOfContourLists; - - mitk::Surface::Pointer m_InterpolationResult; - - // unsigned int m_CurrentNumberOfReducedContours; - - int m_ActiveLabel; - - // std::map m_SegmentationObserverTags; - }; -} -#endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkLabelSetWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkLabelSetWidget.cpp index 95449f48a1..3571708f92 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/QmitkLabelSetWidget.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/QmitkLabelSetWidget.cpp @@ -1,1163 +1,1156 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkLabelSetWidget.h" // mitk #include #include #include #include #include #include #include #include #include -#include #include // Qmitk #include #include #include // Qt #include #include #include #include #include #include #include #include #include #include // itk #include QmitkLabelSetWidget::QmitkLabelSetWidget(QWidget *parent) : QWidget(parent), m_DataStorage(nullptr), m_Completer(nullptr), m_ToolManager(nullptr), m_ProcessingManualSelection(false) { m_Controls.setupUi(this); m_ColorSequenceRainbow.GoToBegin(); m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(true); m_Controls.m_LabelSearchBox->setShowSearchIcon(true); QStringList completionList; completionList << ""; m_Completer = new QCompleter(completionList, this); m_Completer->setCaseSensitivity(Qt::CaseInsensitive); m_Controls.m_LabelSearchBox->setCompleter(m_Completer); connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()), this, SLOT(OnSearchLabel())); auto* renameLabelShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key::Key_L, Qt::CTRL | Qt::Key::Key_R), this); connect(renameLabelShortcut, &QShortcut::activated, this, &QmitkLabelSetWidget::OnRenameLabelShortcutActivated); QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); m_Controls.m_LabelSearchBox->setEnabled(false); m_Controls.m_lblCaption->setText(""); InitializeTableWidget(); } QmitkLabelSetWidget::~QmitkLabelSetWidget() {} void QmitkLabelSetWidget::OnTableViewContextMenuRequested(const QPoint & /*pos*/) { int pixelValue = GetPixelValueOfSelectedItem(); if (-1 == pixelValue) return; QMenu *menu = new QMenu(m_Controls.m_LabelSetTableWidget); if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1) { QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this); mergeAction->setEnabled(true); QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool))); menu->addAction(mergeAction); QAction *removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this); removeLabelsAction->setEnabled(true); QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabels(bool))); menu->addAction(removeLabelsAction); QAction *eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this); eraseLabelsAction->setEnabled(true); QObject::connect(eraseLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabels(bool))); menu->addAction(eraseLabelsAction); } else { QAction *renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this); renameAction->setEnabled(true); QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool))); menu->addAction(renameAction); QAction *removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this); removeAction->setEnabled(true); QObject::connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabel(bool))); menu->addAction(removeAction); QAction *eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this); eraseAction->setEnabled(true); QObject::connect(eraseAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabel(bool))); menu->addAction(eraseAction); QAction *randomColorAction = new QAction(QIcon(":/Qmitk/RandomColor.png"), "Random color", this); randomColorAction->setEnabled(true); QObject::connect(randomColorAction, SIGNAL(triggered(bool)), this, SLOT(OnRandomColor(bool))); menu->addAction(randomColorAction); QAction *viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this); viewOnlyAction->setEnabled(true); QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool))); menu->addAction(viewOnlyAction); QAction *viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this); viewAllAction->setEnabled(true); QObject::connect(viewAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsVisible(bool))); menu->addAction(viewAllAction); QAction *hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this); hideAllAction->setEnabled(true); QObject::connect(hideAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsInvisible(bool))); menu->addAction(hideAllAction); QAction *lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this); lockAllAction->setEnabled(true); QObject::connect(lockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnLockAllLabels(bool))); menu->addAction(lockAllAction); QAction *unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this); unlockAllAction->setEnabled(true); QObject::connect(unlockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnUnlockAllLabels(bool))); menu->addAction(unlockAllAction); QAction *createSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Create surface", this); createSurfaceAction->setEnabled(true); createSurfaceAction->setMenu(new QMenu()); QAction *tmp1 = createSurfaceAction->menu()->addAction(QString("Detailed")); QAction *tmp2 = createSurfaceAction->menu()->addAction(QString("Smoothed")); QObject::connect(tmp1, SIGNAL(triggered(bool)), this, SLOT(OnCreateDetailedSurface(bool))); QObject::connect(tmp2, SIGNAL(triggered(bool)), this, SLOT(OnCreateSmoothedSurface(bool))); menu->addAction(createSurfaceAction); QAction *createMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create mask", this); createMaskAction->setEnabled(true); QObject::connect(createMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMask(bool))); menu->addAction(createMaskAction); QAction *createCroppedMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create cropped mask", this); createCroppedMaskAction->setEnabled(true); QObject::connect(createCroppedMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateCroppedMask(bool))); menu->addAction(createCroppedMaskAction); QSlider *opacitySlider = new QSlider; opacitySlider->setMinimum(0); opacitySlider->setMaximum(100); opacitySlider->setOrientation(Qt::Horizontal); QObject::connect(opacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OnOpacityChanged(int))); QLabel *_OpacityLabel = new QLabel("Opacity: "); QVBoxLayout *_OpacityWidgetLayout = new QVBoxLayout; _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(opacitySlider); QWidget *_OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction *OpacityAction = new QWidgetAction(this); OpacityAction->setDefaultWidget(_OpacityWidget); // QObject::connect( m_OpacityAction, SIGNAL( changed() ), this, SLOT( OpacityActionChanged() ) ); auto workingImage = this->GetWorkingImage(); auto activeLayer = workingImage->GetActiveLayer(); auto label = workingImage->GetLabel(pixelValue, activeLayer); if (nullptr != label) { auto opacity = label->GetOpacity(); opacitySlider->setValue(static_cast(opacity * 100)); } menu->addAction(OpacityAction); } menu->popup(QCursor::pos()); } void QmitkLabelSetWidget::OnUnlockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(false); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnLockAllLabels(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnSetAllLabelsVisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(true); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetAllLabelsInvisible(bool /*value*/) { GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(false); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(bool /*value*/) { mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); workingImage->GetActiveLabelSet()->SetAllLabelsVisible(false); workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->SetVisible(true); workingImage->GetActiveLabelSet()->UpdateLookupTable(pixelValue); this->WaitCursorOn(); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); this->WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnEraseLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to erase the contents of label \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to remove label \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->RemoveLabel(pixelValue, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnRenameLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QmitkNewSegmentationDialog dialog(this, this->GetWorkingImage(), QmitkNewSegmentationDialog::RenameLabel); dialog.SetColor(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetColor()); dialog.SetName(QString::fromStdString(GetWorkingImage()->GetActiveLabelSet()->GetLabel(pixelValue)->GetName())); if (dialog.exec() == QDialog::Rejected) { return; } QString segmentationName = dialog.GetName(); if (segmentationName.isEmpty()) { segmentationName = "Unnamed"; } GetWorkingImage()->GetActiveLabelSet()->RenameLabel(pixelValue, segmentationName.toStdString(), dialog.GetColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnRenameLabelShortcutActivated() { if (m_Controls.m_LabelSetTableWidget->selectedItems().size() == 1) this->OnRenameLabel(true); } void QmitkLabelSetWidget::OnCombineAndCreateMask(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ...to do... // } void QmitkLabelSetWidget::OnCreateMasks(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnCombineAndCreateSurface(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnEraseLabels(bool /*value*/) { QString question = "Do you really want to erase the selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) return; std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for (int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); GetWorkingImage()->EraseLabels(VectorOfLablePixelValues); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabels(bool /*value*/) { QString question = "Do you really want to remove the selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); } ResetAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabels(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to merge selected labels into \""; question.append( QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (ranges.isEmpty()) { return; } std::vector vectorOfSourcePixelValues; foreach (QTableWidgetSelectionRange a, ranges) { for (int i = a.topRow(); i <= a.bottomRow(); ++i) { vectorOfSourcePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt()); } } this->WaitCursorOn(); GetWorkingImage()->MergeLabels(pixelValue, vectorOfSourcePixelValues, GetWorkingImage()->GetActiveLayer()); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnLockedButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, LOCKED_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked()); } } void QmitkLabelSetWidget::OnVisibleButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL)) { row = i; break; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0); int pixelValue = item->data(Qt::UserRole).toInt(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnColorButtonClicked() { int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt(); const mitk::Color &color = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetColor(); QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255); QColor qcolor = QColorDialog::getColor(initial, nullptr, QString("Change color")); if (!qcolor.isValid()) { return; } QPushButton *button = static_cast(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL)); if (!button) { return; } button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(qcolor.red())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.green())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.blue())); styleSheet.append("); border: 0;"); button->setStyleSheet(styleSheet); mitk::Color newColor; newColor.SetRed(qcolor.red() / 255.0); newColor.SetGreen(qcolor.green() / 255.0); newColor.SetBlue(qcolor.blue() / 255.0); GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(newColor); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } } void QmitkLabelSetWidget::OnRandomColor(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage() ->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer()) ->SetColor(m_ColorSequenceRainbow.GetNextColor()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnActiveLabelChanged(int pixelValue) { mitk::LabelSetImage *workingImage = GetWorkingImage(); assert(workingImage); workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); // MITK_INFO << "Active Label set to << " << pixelValue; - mitk::SurfaceBasedInterpolationController *interpolator = mitk::SurfaceBasedInterpolationController::GetInstance(); - if (interpolator) - { - interpolator->SetActiveLabel(pixelValue); - } - workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if (!ranges.empty() && ranges.back().rowCount() == 1) { m_ProcessingManualSelection = true; OnActiveLabelChanged(pixelValue); m_ProcessingManualSelection = false; mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item) { if (!item) return; if (QApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) { this->OnRenameLabelShortcutActivated(); return; } int pixelValue = item->data(Qt::UserRole).toInt(); // OnItemClicked(item); <<-- Double click first call OnItemClicked WaitCursorOn(); mitk::LabelSetImage *workingImage = GetWorkingImage(); workingImage->UpdateCenterOfMass(pixelValue, workingImage->GetActiveLayer()); const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates(); WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } workingImage->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::SelectLabelByPixelValue(mitk::Label::PixelType pixelValue) { if (m_ProcessingManualSelection || !GetWorkingImage()->ExistLabel(pixelValue)) return; for (int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++) { if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue) { m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0)); return; } } } void QmitkLabelSetWidget::InsertTableWidgetItem(mitk::Label *label) { const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append("); border: 0;"); QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); QTableWidgetItem *nameItem = new QTableWidgetItem(text); nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft); // ---!--- // IMPORTANT: ADD PIXELVALUE TO TABLEWIDGETITEM.DATA nameItem->setData(Qt::UserRole, QVariant(label->GetValue())); // ---!--- QPushButton *pbColor = new QPushButton(tableWidget); pbColor->setFixedSize(24, 24); pbColor->setCheckable(false); pbColor->setAutoFillBackground(true); pbColor->setToolTip("Change label color"); pbColor->setStyleSheet(styleSheet); connect(pbColor, SIGNAL(clicked()), this, SLOT(OnColorButtonClicked())); QString transparentStyleSheet = QLatin1String("background-color: transparent; border: 0;"); QPushButton *pbLocked = new QPushButton(tableWidget); pbLocked->setFixedSize(24, 24); QIcon *iconLocked = new QIcon(); auto lockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/lock.svg")); auto unlockIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/unlock.svg")); iconLocked->addPixmap(lockIcon.pixmap(64), QIcon::Normal, QIcon::Off); iconLocked->addPixmap(unlockIcon.pixmap(64), QIcon::Normal, QIcon::On); pbLocked->setIcon(*iconLocked); pbLocked->setIconSize(QSize(24, 24)); pbLocked->setCheckable(true); pbLocked->setToolTip("Lock/unlock label"); pbLocked->setChecked(!label->GetLocked()); pbLocked->setStyleSheet(transparentStyleSheet); connect(pbLocked, SIGNAL(clicked()), this, SLOT(OnLockedButtonClicked())); QPushButton *pbVisible = new QPushButton(tableWidget); pbVisible->setFixedSize(24, 24); pbVisible->setAutoRepeat(false); QIcon *iconVisible = new QIcon(); auto visibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/visible.svg")); auto invisibleIcon = QmitkStyleManager::ThemeIcon(QLatin1String(":/Qmitk/invisible.svg")); iconVisible->addPixmap(visibleIcon.pixmap(64), QIcon::Normal, QIcon::Off); iconVisible->addPixmap(invisibleIcon.pixmap(64), QIcon::Normal, QIcon::On); pbVisible->setIcon(*iconVisible); pbVisible->setIconSize(QSize(24, 24)); pbVisible->setCheckable(true); pbVisible->setToolTip("Show/hide label"); pbVisible->setChecked(!label->GetVisible()); pbVisible->setStyleSheet(transparentStyleSheet); connect(pbVisible, SIGNAL(clicked()), this, SLOT(OnVisibleButtonClicked())); int row = tableWidget->rowCount(); tableWidget->insertRow(row); tableWidget->setRowHeight(row, 24); tableWidget->setItem(row, 0, nameItem); tableWidget->setCellWidget(row, 1, pbLocked); tableWidget->setCellWidget(row, 2, pbColor); tableWidget->setCellWidget(row, 3, pbVisible); tableWidget->selectRow(row); // m_LabelSetImage->SetActiveLabel(label->GetPixelValue()); // m_ToolManager->WorkingDataModified.Send(); // emit activeLabelChanged(label->GetPixelValue()); if (row == 0) { tableWidget->hideRow(row); // hide exterior label } } void QmitkLabelSetWidget::UpdateAllTableWidgetItems() { mitk::LabelSetImage *workingImage = GetWorkingImage(); if (!workingImage) return; // add all labels QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; m_LabelStringList.clear(); for (int i = 0; i < tableWidget->rowCount(); ++i) { UpdateTableWidgetItem(tableWidget->item(i, 0)); m_LabelStringList.append(tableWidget->item(i, 0)->text()); } OnLabelListModified(m_LabelStringList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item) { mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Label *label = workingImage->GetLabel(item->data(Qt::UserRole).toInt(), workingImage->GetActiveLayer()); const mitk::Color &color = label->GetColor(); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[1] * 255)); styleSheet.append(","); styleSheet.append(QString::number(color[2] * 255)); styleSheet.append("); border: 0;"); QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); item->setText(text); QPushButton *pbLocked = dynamic_cast(tableWidget->cellWidget(item->row(), 1)); pbLocked->setChecked(!label->GetLocked()); QPushButton *pbColor = dynamic_cast(tableWidget->cellWidget(item->row(), 2)); pbColor->setStyleSheet(styleSheet); QPushButton *pbVisible = dynamic_cast(tableWidget->cellWidget(item->row(), 3)); pbVisible->setChecked(!label->GetVisible()); if (item->row() == 0) { tableWidget->hideRow(item->row()); // hide exterior label } } void QmitkLabelSetWidget::ResetAllTableWidgetItems() { QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; // remove all rows while (tableWidget->rowCount()) { tableWidget->removeRow(0); } mitk::DataNode * workingNode = GetWorkingNode(); auto workingImage = dynamic_cast(workingNode->GetData()); if (nullptr == workingImage) { return; } // add all labels m_LabelStringList.clear(); mitk::LabelSet::LabelContainerConstIteratorType it = workingImage->GetActiveLabelSet()->IteratorConstBegin(); mitk::LabelSet::LabelContainerConstIteratorType end = workingImage->GetActiveLabelSet()->IteratorConstEnd(); int pixelValue = -1; while (it != end) { InsertTableWidgetItem(it->second); if (workingImage->GetActiveLabel(workingImage->GetActiveLayer()) == it->second) // get active pixelValue = it->first; m_LabelStringList.append(QString(it->second->GetName().c_str())); it++; } SelectLabelByPixelValue(pixelValue); OnLabelListModified(m_LabelStringList); std::stringstream captionText; captionText << "Number of labels: " << workingImage->GetNumberOfLabels(workingImage->GetActiveLayer()) - 1; m_Controls.m_lblCaption->setText(captionText.str().c_str()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); emit LabelSetWidgetReset(); } int QmitkLabelSetWidget::GetPixelValueOfSelectedItem() { if (m_Controls.m_LabelSetTableWidget->currentItem()) { return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt(); } return -1; } QStringList &QmitkLabelSetWidget::GetLabelStringList() { return m_LabelStringList; } void QmitkLabelSetWidget::InitializeTableWidget() { QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget; tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); tableWidget->setTabKeyNavigation(false); tableWidget->setAlternatingRowColors(false); tableWidget->setFocusPolicy(Qt::NoFocus); tableWidget->setColumnCount(4); tableWidget->resizeColumnToContents(NAME_COL); tableWidget->setColumnWidth(LOCKED_COL, 25); tableWidget->setColumnWidth(COLOR_COL, 25); tableWidget->setColumnWidth(VISIBLE_COL, 25); tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); tableWidget->setContextMenuPolicy(Qt::CustomContextMenu); tableWidget->horizontalHeader()->hide(); tableWidget->setSortingEnabled(false); tableWidget->verticalHeader()->hide(); tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); connect(tableWidget, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(OnItemClicked(QTableWidgetItem *))); connect( tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(OnItemDoubleClicked(QTableWidgetItem *))); connect(tableWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(OnTableViewContextMenuRequested(const QPoint &))); } void QmitkLabelSetWidget::OnOpacityChanged(int value) { int pixelValue = GetPixelValueOfSelectedItem(); float opacity = static_cast(value) / 100.0f; GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetOpacity(opacity); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::setEnabled(bool enabled) { QWidget::setEnabled(enabled); UpdateControls(); } void QmitkLabelSetWidget::SetDataStorage(mitk::DataStorage *storage) { m_DataStorage = storage; } void QmitkLabelSetWidget::OnSearchLabel() { std::string text = m_Controls.m_LabelSearchBox->text().toStdString(); int pixelValue = -1; int row = -1; for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i) { if (m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0) { pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt(); row = i; break; } } if (pixelValue == -1) { return; } GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL); if (!nameItem) { return; } m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem); GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); this->WaitCursorOn(); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); m_ToolManager->WorkingDataChanged(); if (pos.GetVnlVector().max_value() > 0.0) { emit goToLabel(pos); } else { GetWorkingImage()->UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer()); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates(); emit goToLabel(pos); } this->WaitCursorOff(); } void QmitkLabelSetWidget::OnLabelListModified(const QStringList &list) { QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(list); } mitk::LabelSetImage *QmitkLabelSetWidget::GetWorkingImage() { mitk::DataNode *workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData()); assert(workingImage); return workingImage; } mitk::DataNode *QmitkLabelSetWidget::GetWorkingNode() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); return workingNode; } void QmitkLabelSetWidget::UpdateControls() { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); bool hasWorkingData = (workingNode != nullptr); m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData); m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData); if (!hasWorkingData) return; QStringListModel *completeModel = static_cast(m_Completer->model()); completeModel->setStringList(GetLabelStringList()); } void QmitkLabelSetWidget::OnCreateCroppedMask(bool) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New(); cropFilter->SetInput(workingImage->CreateLabelMask(pixelValue)); cropFilter->SetBackgroundValue(0); cropFilter->SetMarginFactor(1.15); cropFilter->Update(); maskImage = cropFilter->GetOutput(); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnCreateMask(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::LabelSetImage *workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); maskImage = workingImage->CreateLabelMask(pixelValue); this->WaitCursorOff(); } catch (mitk::Exception &e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, GetWorkingNode()); } void QmitkLabelSetWidget::OnToggleOutline(bool value) { mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); workingNode->SetBoolProperty("labelset.contour.active", value); workingNode->GetData()->Modified(); // fixme: workaround to force data-type rendering (and not only property-type) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnCreateSmoothedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", true); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnCreateDetailedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage *workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", false); surfaceFilter->SetDataStorage(*m_DataStorage); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch (mitk::Exception &e) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::WaitCursorOn() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } void QmitkLabelSetWidget::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkLabelSetWidget::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void QmitkLabelSetWidget::OnThreadedCalculationDone() { mitk::StatusBar::GetInstance()->Clear(); }