diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui
index eaeef0c8a9..d055c5a2d9 100644
--- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui
+++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationControls.ui
@@ -1,760 +1,806 @@
QmitkMultiLabelSegmentationControls
0
0
459
844
0
0
0
0
MS Shell Dlg 2
8
50
false
false
false
false
QmitkSegmentation
-
0
0
Data Selection
-
Patient Image
-
-
-
-
- 0
- 40
-
-
-
+
+
+
+ 0
+ 40
+
+
+
-
Create a new segmentation session
...
:/multilabelsegmentation/NewSegmentationSession_48x48.png:/multilabelsegmentation/NewSegmentationSession_48x48.png
28
28
N
true
-
Segmentation
-
-
-
-
- 0
- 40
-
-
-
+
+
+
+ 0
+ 40
+
+
+
-
Layers
true
false
-
Add a layer to the current segmentation session
...
:/Qmitk/AddLayer_48x48.png:/Qmitk/AddLayer_48x48.png
28
28
true
-
Delete the active layer
...
:/Qmitk/DeleteLayer_48x48.png:/Qmitk/DeleteLayer_48x48.png
28
28
true
-
Qt::Horizontal
0
20
-
Change to the previous available layer
...
:/Qmitk/PreviousLayer_48x48.png:/Qmitk/PreviousLayer_48x48.png
28
28
true
-
Change to the next available layer
...
:/Qmitk/NextLayer_48x48.png:/Qmitk/NextLayer_48x48.png
28
28
true
-
0
0
50
30
40
30
12
Switch to a layer
-
0
-
Labels
true
-
Add a new label to the current segmentation session
...
:/multilabelsegmentation/NewLabel_48x48.png:/multilabelsegmentation/NewLabel_48x48.png
28
28
N
true
-
Lock/Unlock exterior
...
:/Qmitk/UnlockExterior_48x48.png
:/Qmitk/LockExterior_48x48.png:/Qmitk/UnlockExterior_48x48.png
28
28
true
true
+ -
+
+
+ Save LabelSet Preset
+
+
+ ...
+
+
+
+ :/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg:/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg
+
+
+
+ 28
+ 28
+
+
+
+ true
+
+
+
+ -
+
+
+ Load LabelSet Preset
+
+
+ ...
+
+
+
+ :/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg:/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg
+
+
+
+ 28
+ 28
+
+
+
+ true
+
+
+
-
Qt::Horizontal
0
20
-
0
34
Show a table with all labels in the current segmentation session
>>
28
28
true
false
Qt::NoArrow
-
0
0
0
20
-
0
0
QTabWidget::tab-bar { alignment: middle; }
0
true
false
2D Tools
-
0
0
50
false
-
0
0
50
false
-
Qt::Vertical
20
40
3D Tools
-
0
0
50
false
-
0
0
50
false
-
Qt::Vertical
20
40
-
0
0
Interpolation
2
QLayout::SetMinimumSize
2
2
2
2
-
0
0
-
Disabled
-
2D Interpolation
-
3D Interpolation
-
0
0
1
0
0
QLayout::SetMinimumSize
0
0
0
0
-
0
0
0
0
50
false
0
0
QLayout::SetMinimumSize
0
0
0
0
-
0
0
0
50
50
false
0
0
-
Qt::Vertical
20
40
m_LabelSetWidget
groupBox_DataSelection
m_tw2DTools
m_gbInterpolation
groupBox_Layer
groupBox_Labels
-
- QmitkSingleNodeSelectionWidget
- QWidget
- QmitkSingleNodeSelectionWidget.h
- 1
-
-
+
+ QmitkSingleNodeSelectionWidget
+ QWidget
+ QmitkSingleNodeSelectionWidget.h
+ 1
+
+
QmitkToolSelectionBox
QWidget
QmitkToolGUIArea
QWidget
QmitkLabelSetWidget
QWidget
Qmitk/QmitkLabelSetWidget.h
1
QmitkSliceBasedInterpolatorWidget
QWidget
QmitkSliceBasedInterpolatorWidget.h
1
QmitkSurfaceBasedInterpolatorWidget
QWidget
QmitkSurfaceBasedInterpolatorWidget.h
1
QmitkToolGUIArea.h
QmitkToolSelectionBox.h
diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp
index f5f15952e7..b1d6ae2ba9 100644
--- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp
+++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.cpp
@@ -1,1072 +1,1104 @@
/*============================================================================
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 "QmitkMultiLabelSegmentationView.h"
// blueberry
#include
#include
// mitk
#include "mitkApplicationCursor.h"
#include "mitkLabelSetImage.h"
#include "mitkStatusBar.h"
#include "mitkToolManagerProvider.h"
#include "mitkInteractionEventObserver.h"
#include "mitkPlanePositionManager.h"
#include "mitkPluginActivator.h"
#include "mitkSegTool2D.h"
#include "mitkImageTimeSelector.h"
#include "mitkNodePredicateSubGeometry.h"
// Qmitk
+#include
#include "QmitkNewSegmentationDialog.h"
#include "QmitkRenderWindow.h"
#include "QmitkSegmentationOrganNamesHandling.cpp"
+#include "QmitkCreateMultiLabelPresetAction.h"
+#include "QmitkLoadMultiLabelPresetAction.h"
// us
#include
#include
#include
#include
#include
// Qt
#include
#include
#include
#include
#include
#include "tinyxml.h"
#include
#include
const std::string QmitkMultiLabelSegmentationView::VIEW_ID = "org.mitk.views.multilabelsegmentation";
QmitkMultiLabelSegmentationView::QmitkMultiLabelSegmentationView()
: m_Parent(nullptr),
m_IRenderWindowPart(nullptr),
m_ToolManager(nullptr),
m_ReferenceNode(nullptr),
m_WorkingNode(nullptr),
m_AutoSelectionEnabled(false),
m_MouseCursorSet(false)
{
m_SegmentationPredicate = mitk::NodePredicateAnd::New();
m_SegmentationPredicate->AddPredicate(mitk::TNodePredicateDataType::New());
m_SegmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")));
mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New();
mitk::NodePredicateProperty::Pointer isBinary =
mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
mitk::NodePredicateAnd::Pointer isMask = mitk::NodePredicateAnd::New(isBinary, isImage);
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage");
auto isSegment = mitk::NodePredicateDataType::New("Segment");
mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New();
validImages->AddPredicate(mitk::NodePredicateAnd::New(isImage, mitk::NodePredicateNot::New(isSegment)));
validImages->AddPredicate(isDwi);
validImages->AddPredicate(isDti);
validImages->AddPredicate(isOdf);
m_ReferencePredicate = mitk::NodePredicateAnd::New();
m_ReferencePredicate->AddPredicate(validImages);
m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(m_SegmentationPredicate));
m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(isMask));
m_ReferencePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")));
}
QmitkMultiLabelSegmentationView::~QmitkMultiLabelSegmentationView()
{
// Loose LabelSetConnections
OnLooseLabelSetConnection();
}
void QmitkMultiLabelSegmentationView::CreateQtPartControl(QWidget *parent)
{
// setup the basic GUI of this view
m_Parent = parent;
m_Controls.setupUi(parent);
+ m_Controls.m_tbSavePreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-save.svg")));
+ m_Controls.m_tbLoadPreset->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/document-open.svg")));
+
// *------------------------
// * Shortcuts
// *------------------------
QShortcut* visibilityShortcut = new QShortcut(QKeySequence("CTRL+H"), parent);
connect(visibilityShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnVisibilityShortcutActivated);
QShortcut* labelToggleShortcut = new QShortcut(QKeySequence("CTRL+L"), parent);
connect(labelToggleShortcut, &QShortcut::activated, this, &QmitkMultiLabelSegmentationView::OnLabelToggleShortcutActivated);
// *------------------------
// * DATA SELECTION WIDGETS
// *------------------------
m_Controls.m_ReferenceNodeSelector->SetNodePredicate(m_ReferencePredicate);
m_Controls.m_ReferenceNodeSelector->SetDataStorage(this->GetDataStorage());
m_Controls.m_ReferenceNodeSelector->SetInvalidInfo("Select an image");
m_Controls.m_ReferenceNodeSelector->SetPopUpTitel("Select an image");
m_Controls.m_ReferenceNodeSelector->SetPopUpHint("Select an image that should be used to define the geometry and bounds of the segmentation.");
m_Controls.m_WorkingNodeSelector->SetNodePredicate(m_SegmentationPredicate);
m_Controls.m_WorkingNodeSelector->SetDataStorage(this->GetDataStorage());
m_Controls.m_WorkingNodeSelector->SetInvalidInfo("Select a segmentation");
m_Controls.m_WorkingNodeSelector->SetPopUpTitel("Select a segmentation");
m_Controls.m_WorkingNodeSelector->SetPopUpHint("Select a segmentation that should be modified. Only segmentation with the same geometry and within the bounds of the reference image are selected.");
connect(m_Controls.m_ReferenceNodeSelector,
&QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged,
this,&QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged);
connect(m_Controls.m_WorkingNodeSelector,
&QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged,
this,&QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged);
// *------------------------
// * ToolManager
// *------------------------
m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(mitk::ToolManagerProvider::MULTILABEL_SEGMENTATION);
m_ToolManager->SetDataStorage(*(this->GetDataStorage()));
m_ToolManager->InitializeTools();
m_Controls.m_ManualToolSelectionBox2D->SetToolManager(*m_ToolManager);
m_Controls.m_ManualToolSelectionBox3D->SetToolManager(*m_ToolManager);
// *------------------------
// * LabelSetWidget
// *------------------------
m_Controls.m_LabelSetWidget->SetDataStorage(this->GetDataStorage());
m_Controls.m_LabelSetWidget->SetOrganColors(mitk::OrganNamesHandling::GetDefaultOrganColorString());
m_Controls.m_LabelSetWidget->hide();
// *------------------------
// * Interpolation
// *------------------------
m_Controls.m_SurfaceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage()));
m_Controls.m_SliceBasedInterpolatorWidget->SetDataStorage(*(this->GetDataStorage()));
connect(m_Controls.m_cbInterpolation, SIGNAL(activated(int)), this, SLOT(OnInterpolationSelectionChanged(int)));
m_Controls.m_cbInterpolation->setCurrentIndex(0);
m_Controls.m_swInterpolation->hide();
m_Controls.m_gbInterpolation->hide(); // See T27436
QString segTools2D = tr("Add Subtract Fill Erase Paint Wipe 'Region Growing' FastMarching2D Correction 'Live Wire'");
QString segTools3D = tr("Threshold 'Two Thresholds' 'Auto Threshold' 'Multiple Otsu'");
std::regex extSegTool2DRegEx("SegTool2D$");
std::regex extSegTool3DRegEx("SegTool3D$");
auto tools = m_ToolManager->GetTools();
for (const auto &tool : tools)
{
if (std::regex_search(tool->GetNameOfClass(), extSegTool2DRegEx))
{
segTools2D.append(QString(" '%1'").arg(tool->GetName()));
}
else if (std::regex_search(tool->GetNameOfClass(), extSegTool3DRegEx))
{
segTools3D.append(QString(" '%1'").arg(tool->GetName()));
}
}
// *------------------------
// * ToolSelection 2D
// *------------------------
m_Controls.m_ManualToolSelectionBox2D->SetGenerateAccelerators(true);
m_Controls.m_ManualToolSelectionBox2D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer2D);
m_Controls.m_ManualToolSelectionBox2D->SetDisplayedToolGroups(segTools2D.toStdString()); // todo: "Correction
// 'Live Wire'"
m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode(
QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
connect(m_Controls.m_ManualToolSelectionBox2D, SIGNAL(ToolSelected(int)), this, SLOT(OnManualTool2DSelected(int)));
// *------------------------
// * ToolSelection 3D
// *------------------------
m_Controls.m_ManualToolSelectionBox3D->SetGenerateAccelerators(true);
m_Controls.m_ManualToolSelectionBox3D->SetToolGUIArea(m_Controls.m_ManualToolGUIContainer3D);
m_Controls.m_ManualToolSelectionBox3D->SetDisplayedToolGroups(segTools3D.toStdString()); // todo add : FastMarching3D RegionGrowing Watershed
m_Controls.m_ManualToolSelectionBox3D->SetLayoutColumns(2);
m_Controls.m_ManualToolSelectionBox3D->SetEnabledMode(
QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
// *------------------------*
// * Connect PushButtons (pb)
// *------------------------*
connect(m_Controls.m_pbNewLabel, SIGNAL(clicked()), this, SLOT(OnNewLabel()));
+ connect(m_Controls.m_tbSavePreset, SIGNAL(clicked()), this, SLOT(OnSavePreset()));
+ connect(m_Controls.m_tbLoadPreset, SIGNAL(clicked()), this, SLOT(OnLoadPreset()));
connect(m_Controls.m_pbNewSegmentationSession, SIGNAL(clicked()), this, SLOT(OnNewSegmentationSession()));
connect(m_Controls.m_pbShowLabelTable, SIGNAL(toggled(bool)), this, SLOT(OnShowLabelTable(bool)));
// *------------------------*
// * Connect LabelSetWidget
// *------------------------*
connect(m_Controls.m_LabelSetWidget,
SIGNAL(goToLabel(const mitk::Point3D &)),
this,
SLOT(OnGoToLabel(const mitk::Point3D &)));
connect(m_Controls.m_LabelSetWidget, SIGNAL(resetView()), this, SLOT(OnResetView()));
// *------------------------*
// * DATA SLECTION WIDGET
// *------------------------*
m_IRenderWindowPart = this->GetRenderWindowPart();
if (m_IRenderWindowPart)
{
QList controllers;
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController());
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController());
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController());
m_Controls.m_SliceBasedInterpolatorWidget->SetSliceNavigationControllers(controllers);
}
// this->InitializeListeners();
connect(m_Controls.m_btAddLayer, SIGNAL(clicked()), this, SLOT(OnAddLayer()));
connect(m_Controls.m_btDeleteLayer, SIGNAL(clicked()), this, SLOT(OnDeleteLayer()));
connect(m_Controls.m_btPreviousLayer, SIGNAL(clicked()), this, SLOT(OnPreviousLayer()));
connect(m_Controls.m_btNextLayer, SIGNAL(clicked()), this, SLOT(OnNextLayer()));
connect(m_Controls.m_btLockExterior, SIGNAL(toggled(bool)), this, SLOT(OnLockExteriorToggled(bool)));
connect(m_Controls.m_cbActiveLayer, SIGNAL(currentIndexChanged(int)), this, SLOT(OnChangeLayer(int)));
m_Controls.m_btAddLayer->setEnabled(false);
m_Controls.m_btDeleteLayer->setEnabled(false);
m_Controls.m_btNextLayer->setEnabled(false);
m_Controls.m_btPreviousLayer->setEnabled(false);
m_Controls.m_cbActiveLayer->setEnabled(false);
m_Controls.m_pbNewLabel->setEnabled(false);
m_Controls.m_btLockExterior->setEnabled(false);
+ m_Controls.m_tbSavePreset->setEnabled(false);
+ m_Controls.m_tbLoadPreset->setEnabled(false);
m_Controls.m_pbShowLabelTable->setEnabled(false);
// Make sure the GUI notices if appropriate data is already present on creation
m_Controls.m_ReferenceNodeSelector->SetAutoSelectNewNodes(true);
m_Controls.m_WorkingNodeSelector->SetAutoSelectNewNodes(true);
}
void QmitkMultiLabelSegmentationView::Activated()
{
m_ToolManager->SetReferenceData(m_Controls.m_ReferenceNodeSelector->GetSelectedNode());
m_ToolManager->SetWorkingData(m_Controls.m_WorkingNodeSelector->GetSelectedNode());
}
void QmitkMultiLabelSegmentationView::Deactivated()
{
// Not yet implemented
}
void QmitkMultiLabelSegmentationView::Visible()
{
// Not yet implemented
}
void QmitkMultiLabelSegmentationView::Hidden()
{
// Not yet implemented
}
int QmitkMultiLabelSegmentationView::GetSizeFlags(bool width)
{
if (!width)
{
return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL;
}
else
{
return 0;
}
}
int QmitkMultiLabelSegmentationView::ComputePreferredSize(bool width,
int /*availableParallel*/,
int /*availablePerpendicular*/,
int preferredResult)
{
if (width == false)
{
return 100;
}
else
{
return preferredResult;
}
}
/************************************************************************/
/* protected slots */
/************************************************************************/
void QmitkMultiLabelSegmentationView::OnVisibilityShortcutActivated()
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
bool isVisible = false;
workingNode->GetBoolProperty("visible", isVisible);
workingNode->SetVisibility(!isVisible);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkMultiLabelSegmentationView::OnLabelToggleShortcutActivated()
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
WaitCursorOn();
workingImage->GetActiveLabelSet()->SetNextActiveLabel();
workingImage->Modified();
WaitCursorOff();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkMultiLabelSegmentationView::OnManualTool2DSelected(int id)
{
this->ResetMouseCursor();
mitk::StatusBar::GetInstance()->DisplayText("");
if (id >= 0)
{
std::string text = "Active Tool: \"";
text += m_ToolManager->GetToolById(id)->GetName();
text += "\"";
mitk::StatusBar::GetInstance()->DisplayText(text.c_str());
us::ModuleResource resource = m_ToolManager->GetToolById(id)->GetCursorIconResource();
this->SetMouseCursor(resource, 0, 0);
}
}
void QmitkMultiLabelSegmentationView::OnNewLabel()
{
m_ToolManager->ActivateTool(-1);
if (m_ReferenceNode.IsNull())
{
QMessageBox::information(
m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action.");
return;
}
if (nullptr == m_ReferenceNode->GetData())
{
QMessageBox::information(
m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action.");
return;
}
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
if (!workingNode)
{
QMessageBox::information(
m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action.");
return;
}
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
if (!workingImage)
{
QMessageBox::information(
m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action.");
return;
}
QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog(m_Parent);
dialog->SetSuggestionList(mitk::OrganNamesHandling::GetDefaultOrganColorString());
dialog->setWindowTitle("New Label");
int dialogReturnValue = dialog->exec();
if (dialogReturnValue == QDialog::Rejected)
{
return;
}
QString segName = dialog->GetSegmentationName();
if (segName.isEmpty())
{
segName = "Unnamed";
}
workingImage->GetActiveLabelSet()->AddLabel(segName.toStdString(), dialog->GetColor());
UpdateControls();
m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems();
this->ReinitializeViews();
}
+void QmitkMultiLabelSegmentationView::OnSavePreset()
+{
+ QmitkAbstractNodeSelectionWidget::NodeList nodes;
+ nodes.append(m_WorkingNode);
+
+ QmitkCreateMultiLabelPresetAction action;
+ action.Run(nodes);
+}
+
+void QmitkMultiLabelSegmentationView::OnLoadPreset()
+{
+ QmitkAbstractNodeSelectionWidget::NodeList nodes;
+ nodes.append(m_WorkingNode);
+
+ QmitkLoadMultiLabelPresetAction action;
+ action.Run(nodes);
+}
+
void QmitkMultiLabelSegmentationView::OnShowLabelTable(bool value)
{
if (value)
m_Controls.m_LabelSetWidget->show();
else
m_Controls.m_LabelSetWidget->hide();
}
void QmitkMultiLabelSegmentationView::OnNewSegmentationSession()
{
mitk::DataNode *referenceNode = m_Controls.m_ReferenceNodeSelector->GetSelectedNode();
if (!referenceNode)
{
QMessageBox::information(
m_Parent, "New Segmentation Session", "Please load and select a patient image before starting some action.");
return;
}
m_ToolManager->ActivateTool(-1);
mitk::Image::ConstPointer referenceImage = dynamic_cast(referenceNode->GetData());
assert(referenceImage);
const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
unsigned int imageTimeStep = 0;
if (referenceImage->GetTimeGeometry()->IsValidTimePoint(currentTimePoint))
{
imageTimeStep = referenceImage->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint);
}
auto segTemplateImage = referenceImage;
if (referenceImage->GetDimension() > 3)
{
auto result = QMessageBox::question(m_Parent, tr("Generate a static mask?"), tr("The selected image has multiple time steps. You can either generate a simple/static masks resembling the geometry of the first timestep of the image. Or you can generate a dynamic mask that equals the selected image in geometry and number of timesteps; thus a dynamic mask can change over time (e.g. according to the image)."), tr("Yes, generate a static mask"), tr("No, generate a dynamic mask"), QString(), 0, 0);
if (result == 0)
{
auto selector = mitk::ImageTimeSelector::New();
selector->SetInput(referenceImage);
selector->SetTimeNr(0);
selector->Update();
const auto refTimeGeometry = referenceImage->GetTimeGeometry();
auto newTimeGeometry = mitk::ProportionalTimeGeometry::New();
newTimeGeometry->SetFirstTimePoint(refTimeGeometry->GetMinimumTimePoint());
newTimeGeometry->SetStepDuration(refTimeGeometry->GetMaximumTimePoint() - refTimeGeometry->GetMinimumTimePoint());
mitk::Image::Pointer newImage = selector->GetOutput();
newTimeGeometry->SetTimeStepGeometry(referenceImage->GetGeometry(imageTimeStep), 0);
newImage->SetTimeGeometry(newTimeGeometry);
segTemplateImage = newImage;
}
}
QString newName = QString::fromStdString(referenceNode->GetName());
newName.append("-labels");
bool ok = false;
newName = QInputDialog::getText(m_Parent, "New Segmentation Session", "New name:", QLineEdit::Normal, newName, &ok);
if (!ok)
{
return;
}
this->WaitCursorOn();
mitk::LabelSetImage::Pointer workingImage = mitk::LabelSetImage::New();
try
{
workingImage->Initialize(segTemplateImage);
}
catch (mitk::Exception& e)
{
this->WaitCursorOff();
MITK_ERROR << "Exception caught: " << e.GetDescription();
QMessageBox::information(m_Parent, "New Segmentation Session", "Could not create a new segmentation session.\n");
return;
}
this->WaitCursorOff();
mitk::DataNode::Pointer workingNode = mitk::DataNode::New();
workingNode->SetData(workingImage);
workingNode->SetName(newName.toStdString());
workingImage->GetExteriorLabel()->SetProperty("name.parent", mitk::StringProperty::New(referenceNode->GetName().c_str()));
workingImage->GetExteriorLabel()->SetProperty("name.image", mitk::StringProperty::New(newName.toStdString().c_str()));
if (!GetDataStorage()->Exists(workingNode))
{
GetDataStorage()->Add(workingNode, referenceNode);
}
m_Controls.m_WorkingNodeSelector->SetCurrentSelectedNode(workingNode);
OnNewLabel();
}
void QmitkMultiLabelSegmentationView::OnGoToLabel(const mitk::Point3D& pos)
{
if (m_IRenderWindowPart)
m_IRenderWindowPart->SetSelectedPosition(pos);
}
void QmitkMultiLabelSegmentationView::OnResetView()
{
if (m_IRenderWindowPart)
m_IRenderWindowPart->ForceImmediateUpdate();
}
void QmitkMultiLabelSegmentationView::OnAddLayer()
{
m_ToolManager->ActivateTool(-1);
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
QString question = "Do you really want to add a layer to the current segmentation session?";
QMessageBox::StandardButton answerButton = QMessageBox::question(
m_Controls.m_LabelSetWidget, "Add layer", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
if (answerButton != QMessageBox::Yes) return;
try
{
WaitCursorOn();
workingImage->AddLayer();
WaitCursorOff();
}
catch ( mitk::Exception& e )
{
WaitCursorOff();
MITK_ERROR << "Exception caught: " << e.GetDescription();
QMessageBox::information(
m_Controls.m_LabelSetWidget, "Add Layer", "Could not add a new layer. See error log for details.\n");
return;
}
OnNewLabel();
}
void QmitkMultiLabelSegmentationView::OnDeleteLayer()
{
m_ToolManager->ActivateTool(-1);
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
if (workingImage->GetNumberOfLayers() < 2)
return;
QString question = "Do you really want to delete the current layer?";
QMessageBox::StandardButton answerButton = QMessageBox::question(
m_Controls.m_LabelSetWidget, "Delete layer", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
if (answerButton != QMessageBox::Yes)
{
return;
}
try
{
this->WaitCursorOn();
workingImage->RemoveLayer();
this->WaitCursorOff();
}
catch (mitk::Exception& e)
{
this->WaitCursorOff();
MITK_ERROR << "Exception caught: " << e.GetDescription();
QMessageBox::information(m_Controls.m_LabelSetWidget, "Delete Layer",
"Could not delete the currently active layer. See error log for details.\n");
return;
}
UpdateControls();
m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems();
}
void QmitkMultiLabelSegmentationView::OnPreviousLayer()
{
m_ToolManager->ActivateTool(-1);
mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
OnChangeLayer(workingImage->GetActiveLayer() - 1);
}
void QmitkMultiLabelSegmentationView::OnNextLayer()
{
m_ToolManager->ActivateTool(-1);
mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
OnChangeLayer(workingImage->GetActiveLayer() + 1);
}
void QmitkMultiLabelSegmentationView::OnChangeLayer(int layer)
{
m_ToolManager->ActivateTool(-1);
mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage *workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
this->WaitCursorOn();
workingImage->SetActiveLayer(layer);
this->WaitCursorOff();
UpdateControls();
m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems();
}
void QmitkMultiLabelSegmentationView::OnDeactivateActiveTool()
{
m_ToolManager->ActivateTool(-1);
}
void QmitkMultiLabelSegmentationView::OnLockExteriorToggled(bool checked)
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
assert(workingNode);
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
assert(workingImage);
workingImage->GetLabel(0)->SetLocked(checked);
}
void QmitkMultiLabelSegmentationView::OnReferenceSelectionChanged(QList /*nodes*/)
{
m_ToolManager->ActivateTool(-1);
auto refNode = m_Controls.m_ReferenceNodeSelector->GetSelectedNode();
m_ReferenceNode = refNode;
m_ToolManager->SetReferenceData(m_ReferenceNode);
if (m_ReferenceNode.IsNotNull())
{
auto segPredicate = mitk::NodePredicateAnd::New(m_SegmentationPredicate.GetPointer(), mitk::NodePredicateSubGeometry::New(refNode->GetData()->GetGeometry()));
m_Controls.m_WorkingNodeSelector->SetNodePredicate(segPredicate);
if (m_AutoSelectionEnabled)
{
// hide all image nodes to later show only the automatically selected ones
mitk::DataStorage::SetOfObjects::ConstPointer patientNodes = GetDataStorage()->GetSubset(m_ReferencePredicate);
for (mitk::DataStorage::SetOfObjects::const_iterator iter = patientNodes->begin(); iter != patientNodes->end(); ++iter)
{
(*iter)->SetVisibility(false);
}
}
m_ReferenceNode->SetVisibility(true);
}
UpdateControls();
}
void QmitkMultiLabelSegmentationView::OnSegmentationSelectionChanged(QList /*nodes*/)
{
m_ToolManager->ActivateTool(-1);
if (m_WorkingNode.IsNotNull())
OnLooseLabelSetConnection();
m_WorkingNode = m_Controls.m_WorkingNodeSelector->GetSelectedNode();
m_ToolManager->SetWorkingData(m_WorkingNode);
if (m_WorkingNode.IsNotNull())
{
OnEstablishLabelSetConnection();
if (m_AutoSelectionEnabled)
{
// hide all segmentation nodes to later show only the automatically selected ones
mitk::DataStorage::SetOfObjects::ConstPointer segmentationNodes = GetDataStorage()->GetSubset(m_SegmentationPredicate);
for (mitk::DataStorage::SetOfObjects::const_iterator iter = segmentationNodes->begin(); iter != segmentationNodes->end(); ++iter)
{
(*iter)->SetVisibility(false);
}
}
m_WorkingNode->SetVisibility(true);
}
UpdateControls();
if (m_WorkingNode.IsNotNull())
{
m_Controls.m_LabelSetWidget->ResetAllTableWidgetItems();
this->ReinitializeViews();
}
}
void QmitkMultiLabelSegmentationView::OnInterpolationSelectionChanged(int index)
{
if (index == 1)
{
m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);//OnToggleWidgetActivation(false);
m_Controls.m_swInterpolation->setCurrentIndex(0);
m_Controls.m_swInterpolation->show();
}
else if (index == 2)
{
m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);
m_Controls.m_swInterpolation->setCurrentIndex(1);
m_Controls.m_swInterpolation->show();
}
else
{
m_Controls.m_SurfaceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);
m_Controls.m_SliceBasedInterpolatorWidget->m_Controls.m_btStart->setChecked(false);
m_Controls.m_swInterpolation->setCurrentIndex(2);
m_Controls.m_swInterpolation->hide();
}
}
/************************************************************************/
/* protected */
/************************************************************************/
void QmitkMultiLabelSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if (m_Parent && m_WorkingNode.IsNotNull())
{
m_AutoSelectionEnabled = prefs->GetBool("auto selection", false);
mitk::BoolProperty::Pointer drawOutline = mitk::BoolProperty::New(prefs->GetBool("draw outline", true));
mitk::BoolProperty::Pointer volumeRendering = mitk::BoolProperty::New(prefs->GetBool("volume rendering", false));
mitk::LabelSetImage* labelSetImage;
mitk::DataNode* segmentation;
// iterate all segmentations (binary (single label) and LabelSetImages)
mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
mitk::NodePredicateOr::Pointer allSegmentationsPredicate = mitk::NodePredicateOr::New(isBinaryPredicate, m_SegmentationPredicate);
mitk::DataStorage::SetOfObjects::ConstPointer allSegmentations = GetDataStorage()->GetSubset(allSegmentationsPredicate);
for (mitk::DataStorage::SetOfObjects::const_iterator it = allSegmentations->begin(); it != allSegmentations->end(); ++it)
{
segmentation = *it;
labelSetImage = dynamic_cast(segmentation->GetData());
if (nullptr != labelSetImage)
{
// segmentation node is a multi label segmentation
segmentation->SetProperty("labelset.contour.active", drawOutline);
//segmentation->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
segmentation->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
segmentation->GetData()->Modified();
}
else if (nullptr != segmentation->GetData())
{
// node is actually a 'single label' segmentation,
// but its outline property can be set in the 'multi label' segmentation preference page as well
bool isBinary = false;
segmentation->GetBoolProperty("binary", isBinary);
if (isBinary)
{
segmentation->SetProperty("outline binary", drawOutline);
segmentation->SetProperty("outline width", mitk::FloatProperty::New(2.0));
//segmentation->SetProperty("opacity", mitk::FloatProperty::New(drawOutline->GetValue() ? 1.0f : 0.3f));
segmentation->SetProperty("volumerendering", volumeRendering);
// force render window update to show outline
segmentation->GetData()->Modified();
}
}
else
{
// "interpolation feedback" data nodes have binary flag but don't have a data set. So skip them for now.
MITK_INFO << "DataNode " << segmentation->GetName() << " doesn't contain a base data.";
}
}
}
}
void QmitkMultiLabelSegmentationView::NodeRemoved(const mitk::DataNode *node)
{
bool isHelperObject(false);
node->GetBoolProperty("helper object", isHelperObject);
if (isHelperObject)
{
return;
}
if (m_ReferenceNode.IsNotNull() && dynamic_cast(node->GetData()))
{
// remove all possible contour markers of the segmentation
mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = this->GetDataStorage()->GetDerivations(
node, mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true)));
ctkPluginContext *context = mitk::PluginActivator::getContext();
ctkServiceReference ppmRef = context->getServiceReference();
mitk::PlanePositionManagerService *service = context->getService(ppmRef);
for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
{
std::string nodeName = node->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int id = atof(nodeName.substr(t + 1).c_str()) - 1;
service->RemovePlanePosition(id);
this->GetDataStorage()->Remove(it->Value());
}
context->ungetService(ppmRef);
service = nullptr;
}
}
void QmitkMultiLabelSegmentationView::OnEstablishLabelSetConnection()
{
if (m_WorkingNode.IsNull())
{
return;
}
mitk::LabelSetImage *workingImage = dynamic_cast(m_WorkingNode->GetData());
assert(workingImage);
workingImage->GetActiveLabelSet()->AddLabelEvent += mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems);
workingImage->GetActiveLabelSet()->RemoveLabelEvent += mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems);
workingImage->GetActiveLabelSet()->ModifyLabelEvent += mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems);
workingImage->GetActiveLabelSet()->AllLabelsModifiedEvent += mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems);
workingImage->GetActiveLabelSet()->ActiveLabelEvent +=
mitk::MessageDelegate1(m_Controls.m_LabelSetWidget,
&QmitkLabelSetWidget::SelectLabelByPixelValue);
// Removed in T27851 to have a chance to react to AfterChangeLayerEvent. Did it brake something?
// workingImage->BeforeChangeLayerEvent += mitk::MessageDelegate(
// this, &QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection);
workingImage->AfterChangeLayerEvent += mitk::MessageDelegate(
this, &QmitkMultiLabelSegmentationView::UpdateControls);
}
void QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection()
{
if (m_WorkingNode.IsNull())
return;
auto* workingImage = dynamic_cast(m_WorkingNode->GetData());
if (nullptr == workingImage)
return; // data (type) was changed in-place, e.g. LabelSetImage -> Image
// Reset LabelSetWidget Events
workingImage->GetActiveLabelSet()->AddLabelEvent -= mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems);
workingImage->GetActiveLabelSet()->RemoveLabelEvent -= mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::ResetAllTableWidgetItems);
workingImage->GetActiveLabelSet()->ModifyLabelEvent -= mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems);
workingImage->GetActiveLabelSet()->AllLabelsModifiedEvent -= mitk::MessageDelegate(
m_Controls.m_LabelSetWidget, &QmitkLabelSetWidget::UpdateAllTableWidgetItems);
workingImage->GetActiveLabelSet()->ActiveLabelEvent -=
mitk::MessageDelegate1(m_Controls.m_LabelSetWidget,
&QmitkLabelSetWidget::SelectLabelByPixelValue);
// Removed in T27851 to have a chance to react to AfterChangeLayerEvent. Did it brake something?
// workingImage->BeforeChangeLayerEvent -= mitk::MessageDelegate(
// this, &QmitkMultiLabelSegmentationView::OnLooseLabelSetConnection);
workingImage->AfterChangeLayerEvent -= mitk::MessageDelegate(
this, &QmitkMultiLabelSegmentationView::UpdateControls);
}
void QmitkMultiLabelSegmentationView::SetFocus()
{
}
void QmitkMultiLabelSegmentationView::UpdateControls()
{
mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0);
bool hasReferenceNode = referenceNode != nullptr;
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
bool hasValidWorkingNode = workingNode != nullptr;
m_Controls.m_pbNewLabel->setEnabled(false);
m_Controls.m_gbInterpolation->setEnabled(false);
m_Controls.m_SliceBasedInterpolatorWidget->setEnabled(false);
m_Controls.m_SurfaceBasedInterpolatorWidget->setEnabled(false);
m_Controls.m_LabelSetWidget->setEnabled(false);
m_Controls.m_btAddLayer->setEnabled(false);
m_Controls.m_btDeleteLayer->setEnabled(false);
m_Controls.m_cbActiveLayer->setEnabled(false);
m_Controls.m_btPreviousLayer->setEnabled(false);
m_Controls.m_btNextLayer->setEnabled(false);
m_Controls.m_btLockExterior->setChecked(false);
m_Controls.m_btLockExterior->setEnabled(false);
+ m_Controls.m_tbSavePreset->setEnabled(false);
+ m_Controls.m_tbLoadPreset->setEnabled(false);
m_Controls.m_pbShowLabelTable->setChecked(false);
m_Controls.m_pbShowLabelTable->setEnabled(false);
m_Controls.m_ManualToolSelectionBox3D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithReferenceAndWorkingDataVisible);
if (hasValidWorkingNode)
{
// TODO adapt tool manager so that this check is done there, e.g. convenience function
mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData());
hasValidWorkingNode = workingImage != nullptr;
if (hasValidWorkingNode)
{
m_Controls.m_pbNewLabel->setEnabled(true);
m_Controls.m_btLockExterior->setEnabled(true);
+ m_Controls.m_tbSavePreset->setEnabled(true);
+ m_Controls.m_tbLoadPreset->setEnabled(true);
m_Controls.m_pbShowLabelTable->setEnabled(true);
m_Controls.m_gbInterpolation->setEnabled(true);
m_Controls.m_SliceBasedInterpolatorWidget->setEnabled(true);
m_Controls.m_SurfaceBasedInterpolatorWidget->setEnabled(true);
m_Controls.m_LabelSetWidget->setEnabled(true);
m_Controls.m_btAddLayer->setEnabled(true);
int activeLayer = workingImage->GetActiveLayer();
int numberOfLayers = workingImage->GetNumberOfLayers();
m_Controls.m_cbActiveLayer->blockSignals(true);
m_Controls.m_cbActiveLayer->clear();
for (unsigned int lidx = 0; lidx < workingImage->GetNumberOfLayers(); ++lidx)
{
m_Controls.m_cbActiveLayer->addItem(QString::number(lidx));
}
m_Controls.m_cbActiveLayer->setCurrentIndex(activeLayer);
m_Controls.m_cbActiveLayer->blockSignals(false);
m_Controls.m_cbActiveLayer->setEnabled(numberOfLayers > 1);
m_Controls.m_btDeleteLayer->setEnabled(numberOfLayers > 1);
m_Controls.m_btPreviousLayer->setEnabled(activeLayer > 0);
m_Controls.m_btNextLayer->setEnabled(activeLayer != numberOfLayers - 1);
m_Controls.m_btLockExterior->setChecked(workingImage->GetLabel(0, activeLayer)->GetLocked());
m_Controls.m_pbShowLabelTable->setChecked(workingImage->GetNumberOfLabels() > 1 /*1st is exterior*/);
//MLI TODO
//m_Controls.m_ManualToolSelectionBox2D->SetEnabledMode(QmitkToolSelectionBox::EnabledWithWorkingDataVisible);
}
}
if (hasValidWorkingNode && hasReferenceNode)
{
int layer = -1;
referenceNode->GetIntProperty("layer", layer);
workingNode->SetIntProperty("layer", layer + 1);
}
this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_ALL);
}
void QmitkMultiLabelSegmentationView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart)
{
if (m_IRenderWindowPart != renderWindowPart)
{
m_IRenderWindowPart = renderWindowPart;
m_Parent->setEnabled(true);
QList controllers;
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController());
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController());
controllers.push_back(m_IRenderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController());
m_Controls.m_SliceBasedInterpolatorWidget->SetSliceNavigationControllers(controllers);
}
}
void QmitkMultiLabelSegmentationView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* /*renderWindowPart*/)
{
m_ToolManager->ActivateTool(-1);
m_IRenderWindowPart = nullptr;
m_Parent->setEnabled(false);
}
void QmitkMultiLabelSegmentationView::ResetMouseCursor()
{
if (m_MouseCursorSet)
{
mitk::ApplicationCursor::GetInstance()->PopCursor();
m_MouseCursorSet = false;
}
}
void QmitkMultiLabelSegmentationView::SetMouseCursor(const us::ModuleResource resource, int hotspotX, int hotspotY)
{
// Remove previously set mouse cursor
if (m_MouseCursorSet)
this->ResetMouseCursor();
if (resource)
{
us::ModuleResourceStream cursor(resource, std::ios::binary);
mitk::ApplicationCursor::GetInstance()->PushCursor(cursor, hotspotX, hotspotY);
m_MouseCursorSet = true;
}
}
void QmitkMultiLabelSegmentationView::InitializeListeners()
{
if (m_Interactor.IsNull())
{
us::Module* module = us::GetModuleContext()->GetModule();
std::vector resources = module->FindResources("/", "*", true);
for (std::vector::iterator iter = resources.begin(); iter != resources.end(); ++iter)
{
MITK_INFO << iter->GetResourcePath();
}
m_Interactor = mitk::SegmentationInteractor::New();
if (!m_Interactor->LoadStateMachine("SegmentationInteraction.xml", module))
{
MITK_WARN << "Error loading state machine";
}
if (!m_Interactor->SetEventConfig("ConfigSegmentation.xml", module))
{
MITK_WARN << "Error loading state machine configuration";
}
// Register as listener via micro services
us::ServiceProperties props;
props["name"] = std::string("SegmentationInteraction");
m_ServiceRegistration =
us::GetModuleContext()->RegisterService(m_Interactor.GetPointer(), props);
}
}
void QmitkMultiLabelSegmentationView::ReinitializeViews() const
{
if (m_ReferenceNode.IsNotNull() && nullptr != m_ReferenceNode->GetData())
{
const auto currentTimePoint = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint();
unsigned int imageTimeStep = 0;
if (m_ReferenceNode->GetData()->GetTimeGeometry()->IsValidTimePoint(currentTimePoint))
{
imageTimeStep = m_ReferenceNode->GetData()->GetTimeGeometry()->TimePointToTimeStep(currentTimePoint);
}
mitk::RenderingManager::GetInstance()->InitializeViews(m_ReferenceNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->SetPos(imageTimeStep);
}
}
diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h
index 9d6bc16a0f..adb0de5c19 100644
--- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h
+++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/QmitkMultiLabelSegmentationView.h
@@ -1,171 +1,177 @@
/*============================================================================
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 QmitkMultiLabelSegmentationView_h
#define QmitkMultiLabelSegmentationView_h
#include
#include "mitkSegmentationInteractor.h"
#include
#include "ui_QmitkMultiLabelSegmentationControls.h"
// berry
#include
class QmitkRenderWindow;
/**
* \ingroup ToolManagerEtAl
* \ingroup org_mitk_gui_qt_multilabelsegmentation_internal
*/
class QmitkMultiLabelSegmentationView : public QmitkAbstractView, public mitk::ILifecycleAwarePart
{
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkMultiLabelSegmentationView();
~QmitkMultiLabelSegmentationView() override;
typedef std::map NodeTagMapType;
// GUI setup
void CreateQtPartControl(QWidget *parent) override;
// ILifecycleAwarePart interface
public:
void Activated() override;
void Deactivated() override;
void Visible() override;
void Hidden() override;
virtual int GetSizeFlags(bool width);
virtual int ComputePreferredSize(bool width,
int /*availableParallel*/,
int /*availablePerpendicular*/,
int preferredResult);
protected slots:
// reaction to the shortcut for toggling the visibility of the working node
void OnVisibilityShortcutActivated();
// reaction to the shortcut for iterating over all labels
void OnLabelToggleShortcutActivated();
// reaction to the selection of any 2D segmentation tool
void OnManualTool2DSelected(int id);
// reaction to button "New Label"
void OnNewLabel();
+ // raction to button "Save Preset"
+ void OnSavePreset();
+
+ // reaction to button "Load Preset"
+ void OnLoadPreset();
+
// reaction to button "Show Label Table"
void OnShowLabelTable(bool value);
// reaction to button "New Segmentation Session"
void OnNewSegmentationSession();
// reaction to signal "goToLabel" from labelset widget
void OnGoToLabel(const mitk::Point3D &pos);
void OnResetView();
// reaction to the button "Add Layer"
void OnAddLayer();
// reaction to the button "Delete Layer"
void OnDeleteLayer();
// reaction to the button "Previous Layer"
void OnPreviousLayer();
// reaction to the button "Next Layer"
void OnNextLayer();
// reaction to the combobox change "Change Layer"
void OnChangeLayer(int);
// reaction to the button "Deactive Active Tool"
void OnDeactivateActiveTool();
// reaction to the button "Lock exterior"
void OnLockExteriorToggled(bool);
// reaction to the selection of a new patient (reference) image in the DataStorage combobox
void OnReferenceSelectionChanged(QList nodes);
// reaction to the selection of a new Segmentation (working) image in the DataStorage combobox
void OnSegmentationSelectionChanged(QList nodes);
// reaction to ...
void OnInterpolationSelectionChanged(int);
protected:
// reimplemented from QmitkAbstractView
void OnPreferencesChanged(const berry::IBerryPreferences* prefs) override;
// reimplemented from QmitkAbstractView
void NodeRemoved(const mitk::DataNode* node) override;
void OnEstablishLabelSetConnection();
void OnLooseLabelSetConnection();
void SetFocus() override;
void UpdateControls();
void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart);
void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart);
void ResetMouseCursor();
void SetMouseCursor(const us::ModuleResource, int hotspotX, int hotspotY);
void InitializeListeners();
void ReinitializeViews() const;
/// \brief the Qt parent of our GUI (NOT of this object)
QWidget *m_Parent;
/// \brief Qt GUI file
Ui::QmitkMultiLabelSegmentationControls m_Controls;
mitk::IRenderWindowPart *m_IRenderWindowPart;
mitk::ToolManager *m_ToolManager;
mitk::DataNode::Pointer m_ReferenceNode;
mitk::DataNode::Pointer m_WorkingNode;
mitk::NodePredicateAnd::Pointer m_ReferencePredicate;
mitk::NodePredicateAnd::Pointer m_SegmentationPredicate;
bool m_AutoSelectionEnabled;
bool m_MouseCursorSet;
mitk::SegmentationInteractor::Pointer m_Interactor;
/**
* Reference to the service registration of the observer,
* it is needed to unregister the observer on unload.
*/
us::ServiceRegistration m_ServiceRegistration;
};
#endif // QmitkMultiLabelSegmentationView_h