diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/files.cmake b/Modules/Bundles/org.mitk.gui.qt.segmentation/files.cmake
index 7d4c80c548..aa73a6dc4d 100644
--- a/Modules/Bundles/org.mitk.gui.qt.segmentation/files.cmake
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/files.cmake
@@ -1,52 +1,57 @@
SET(SRC_CPP_FILES
QmitkSegmentationPreferencePage.cpp
)
SET(INTERNAL_CPP_FILES
mitkPluginActivator.cpp
QmitkSegmentationView.cpp
QmitkSegmentationPostProcessing.cpp
QmitkThresholdAction.cpp
QmitkCreatePolygonModelAction.cpp
QmitkStatisticsAction.cpp
QmitkAutocropAction.cpp
+ QmitkBooleanOperationsView.cpp
QmitkDeformableClippingPlaneView.cpp
)
SET(UI_FILES
src/internal/QmitkSegmentationControls.ui
+ src/internal/QmitkBooleanOperationsView.ui
src/internal/QmitkDeformableClippingPlaneViewControls.ui
)
SET(MOC_H_FILES
src/QmitkSegmentationPreferencePage.h
src/internal/mitkPluginActivator.h
src/internal/QmitkSegmentationView.h
src/internal/QmitkSegmentationPostProcessing.h
src/internal/QmitkThresholdAction.h
src/internal/QmitkCreatePolygonModelAction.h
src/internal/QmitkStatisticsAction.h
src/internal/QmitkAutocropAction.h
+ src/internal/QmitkBooleanOperationsView.h
src/internal/QmitkDeformableClippingPlaneView.h
)
SET(CACHED_RESOURCE_FILES
resources/segmentation.png
+ resources/boolean.png
resources/deformablePlane.png
plugin.xml
)
SET(QRC_FILES
resources/segmentation.qrc
+ resources/boolean.qrc
)
SET(CPP_FILES)
foreach(file ${SRC_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
SET(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/plugin.xml b/Modules/Bundles/org.mitk.gui.qt.segmentation/plugin.xml
index c39189e193..2be45b9c15 100644
--- a/Modules/Bundles/org.mitk.gui.qt.segmentation/plugin.xml
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/plugin.xml
@@ -1,42 +1,41 @@
-
-
-
-
+
+ name="Clipping Plane"
+ class="QmitkDeformableClippingPlaneView"
+ icon="resources/deformablePlane.png" />
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.png b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.png
new file mode 100644
index 0000000000..6eeb2cdf8b
Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.png differ
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.qrc b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.qrc
new file mode 100644
index 0000000000..6094c0644f
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/boolean.qrc
@@ -0,0 +1,7 @@
+
+
+ btnDifference.png
+ btnIntersection.png
+ btnUnion.png
+
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnDifference.png b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnDifference.png
new file mode 100644
index 0000000000..918548c943
Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnDifference.png differ
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnIntersection.png b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnIntersection.png
new file mode 100644
index 0000000000..93eb7af027
Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnIntersection.png differ
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnUnion.png b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnUnion.png
new file mode 100644
index 0000000000..6ab4e6d79c
Binary files /dev/null and b/Modules/Bundles/org.mitk.gui.qt.segmentation/resources/btnUnion.png differ
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.cpp b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.cpp
new file mode 100644
index 0000000000..9c4cceeb1f
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.cpp
@@ -0,0 +1,244 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Module: $RCSfile$
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "QmitkBooleanOperationsView.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+QmitkBooleanOperationsView::QmitkBooleanOperationsView()
+ : m_Parent(NULL)
+{
+}
+
+QmitkBooleanOperationsView::~QmitkBooleanOperationsView()
+{
+}
+
+void QmitkBooleanOperationsView::CreateQtPartControl(QWidget *parent)
+{
+ mitk::DataStorage::Pointer dataStorage = GetDefaultDataStorage();
+
+ mitk::NodePredicateAnd::Pointer segmentationPredicate = mitk::NodePredicateAnd::New(
+ mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)),
+ mitk::NodePredicateNot::New(
+ mitk::NodePredicateProperty::New("helper object")));
+
+ m_Parent = parent;
+
+ m_Controls.setupUi(parent);
+
+ m_Controls.cmbSegmentationImage1->SetDataStorage(dataStorage);
+ m_Controls.cmbSegmentationImage1->SetPredicate(segmentationPredicate);
+
+ m_Controls.cmbSegmentationImage2->SetPredicate(segmentationPredicate);
+ m_Controls.cmbSegmentationImage2->SetDataStorage(dataStorage);
+
+ connect(m_Controls.cmbSegmentationImage1, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSegmentationImage1Changed(const mitk::DataNode *)));
+ connect(m_Controls.cmbSegmentationImage2, SIGNAL(OnSelectionChanged(const mitk::DataNode *)), this, SLOT(OnSegmentationImage2Changed(const mitk::DataNode *)));
+ connect(m_Controls.btnDifference, SIGNAL(clicked()), this, SLOT(OnDifferenceButtonClicked()));
+ connect(m_Controls.btnUnion, SIGNAL(clicked()), this, SLOT(OnUnionButtonClicked()));
+ connect(m_Controls.btnIntersection, SIGNAL(clicked()), this, SLOT(OnIntersectionButtonClicked()));
+}
+
+bool QmitkBooleanOperationsView::CheckSegmentationImages()
+{
+ mitk::Image::Pointer image1 = dynamic_cast(m_Controls.cmbSegmentationImage1->GetSelectedNode()->GetData());
+ mitk::Image::Pointer image2 = dynamic_cast(m_Controls.cmbSegmentationImage2->GetSelectedNode()->GetData());
+
+ if (image1.IsNull() || image2.IsNull())
+ {
+ MITK_ERROR << "At least one input segmentation image is invalid!";
+ return false;
+ }
+
+ if (image1->GetDimension() != image2->GetDimension())
+ {
+ MITK_ERROR << "Dimensions of input segmentation images are different!";
+ return false;
+ }
+
+ if (image1->GetDimension() == 4)
+ {
+ unsigned int time = GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime()->GetPos();
+
+ if (time >= image1->GetDimension(3) || time >= image2->GetDimension(3))
+ {
+ MITK_ERROR << "At least one input segmentation image has no data for current time slice!";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+mitk::Image::Pointer QmitkBooleanOperationsView::To3D(const mitk::Image::Pointer &image)
+{
+ if (image->GetDimension() == 4)
+ {
+ mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New();
+
+ imageTimeSelector->SetInput(image);
+ imageTimeSelector->SetTimeNr(static_cast(GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime()->GetPos()));
+
+ imageTimeSelector->UpdateLargestPossibleRegion();
+
+ return imageTimeSelector->GetOutput();
+ }
+ else
+ {
+ return image;
+ }
+}
+
+void QmitkBooleanOperationsView::AddToDataStorage(const mitk::Image::Pointer &image, const std::string &prefix) const
+{
+ mitk::DataNode::Pointer dataNode = mitk::DataNode::New();
+
+ dataNode->SetBoolProperty("binary", true);
+ dataNode->SetName(prefix + m_Controls.cmbSegmentationImage2->GetSelectedNode()->GetName());
+ dataNode->SetData(image);
+
+ GetDefaultDataStorage()->Add(dataNode, m_Controls.cmbSegmentationImage1->GetSelectedNode());
+}
+
+void QmitkBooleanOperationsView::EnableButtons(bool enable)
+{
+ m_Controls.lblInputImagesWarning->setVisible(!enable);
+ m_Controls.btnDifference->setEnabled(enable);
+ m_Controls.btnUnion->setEnabled(enable);
+ m_Controls.btnIntersection->setEnabled(enable);
+}
+
+void QmitkBooleanOperationsView::DisableButtons()
+{
+ EnableButtons(false);
+}
+
+void QmitkBooleanOperationsView::OnSegmentationImage1Changed(const mitk::DataNode *dataNode)
+{
+ if (dataNode != m_Controls.cmbSegmentationImage2->GetSelectedNode())
+ EnableButtons();
+ else
+ DisableButtons();
+}
+
+void QmitkBooleanOperationsView::OnSegmentationImage2Changed(const mitk::DataNode *dataNode)
+{
+ if (dataNode != m_Controls.cmbSegmentationImage1->GetSelectedNode())
+ EnableButtons();
+ else
+ DisableButtons();
+}
+
+void QmitkBooleanOperationsView::OnDifferenceButtonClicked()
+{
+ if (!CheckSegmentationImages())
+ return;
+
+ mitk::Image::Pointer image1 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage1->GetSelectedNode()->GetData()));
+ mitk::Image::Pointer image2 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage2->GetSelectedNode()->GetData()));
+
+ typedef itk::Image ImageType;
+
+ ImageType::Pointer itkImage1 = ImageType::New();
+ ImageType::Pointer itkImage2 = ImageType::New();
+
+ mitk::CastToItkImage(image1, itkImage1);
+ mitk::CastToItkImage(image2, itkImage2);
+
+ itk::NotImageFilter::Pointer notFilter = itk::NotImageFilter::New();
+ notFilter->SetInput(itkImage2);
+
+ itk::AndImageFilter::Pointer andFilter = itk::AndImageFilter::New();
+ andFilter->SetInput1(itkImage1);
+ andFilter->SetInput2(notFilter->GetOutput());
+ andFilter->UpdateLargestPossibleRegion();
+
+ mitk::Image::Pointer image3 = mitk::Image::New();
+ mitk::CastToMitkImage(andFilter->GetOutput(), image3);
+
+ image3->DisconnectPipeline();
+
+ AddToDataStorage(image3, "Difference_");
+}
+
+void QmitkBooleanOperationsView::OnUnionButtonClicked()
+{
+ if (!CheckSegmentationImages())
+ return;
+
+ mitk::Image::Pointer image1 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage1->GetSelectedNode()->GetData()));
+ mitk::Image::Pointer image2 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage2->GetSelectedNode()->GetData()));
+
+ typedef itk::Image ImageType;
+
+ ImageType::Pointer itkImage1 = ImageType::New();
+ ImageType::Pointer itkImage2 = ImageType::New();
+
+ mitk::CastToItkImage(image1, itkImage1);
+ mitk::CastToItkImage(image2, itkImage2);
+
+ itk::OrImageFilter::Pointer orFilter = itk::OrImageFilter::New();
+ orFilter->SetInput1(itkImage1);
+ orFilter->SetInput2(itkImage2);
+ orFilter->UpdateLargestPossibleRegion();
+
+ mitk::Image::Pointer image3 = mitk::Image::New();
+ mitk::CastToMitkImage(orFilter->GetOutput(), image3);
+
+ image3->DisconnectPipeline();
+
+ AddToDataStorage(image3, "Union_");
+}
+
+void QmitkBooleanOperationsView::OnIntersectionButtonClicked()
+{
+ if (!CheckSegmentationImages())
+ return;
+
+ mitk::Image::Pointer image1 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage1->GetSelectedNode()->GetData()));
+ mitk::Image::Pointer image2 = To3D(dynamic_cast(m_Controls.cmbSegmentationImage2->GetSelectedNode()->GetData()));
+
+ typedef itk::Image ImageType;
+
+ ImageType::Pointer itkImage1 = ImageType::New();
+ ImageType::Pointer itkImage2 = ImageType::New();
+
+ mitk::CastToItkImage(image1, itkImage1);
+ mitk::CastToItkImage(image2, itkImage2);
+
+ itk::AndImageFilter::Pointer andFilter = itk::AndImageFilter::New();
+ andFilter->SetInput1(itkImage1);
+ andFilter->SetInput2(itkImage2);
+ andFilter->UpdateLargestPossibleRegion();
+
+ mitk::Image::Pointer image3 = mitk::Image::New();
+ mitk::CastToMitkImage(andFilter->GetOutput(), image3);
+
+ image3->DisconnectPipeline();
+
+ AddToDataStorage(image3, "Intersection_");
+}
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.h b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.h
new file mode 100644
index 0000000000..ebf43cde57
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.h
@@ -0,0 +1,54 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Module: $RCSfile$
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+Copyright (c) German Cancer Research Center, Division of Medical and
+Biological Informatics. All rights reserved.
+See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef QMITKBOOLEANOPERATIONSVIEW_H
+#define QMITKBOOLEANOPERATIONSVIEW_H
+
+#include
+#include
+
+class QmitkBooleanOperationsView : public QmitkFunctionality
+{
+ Q_OBJECT
+
+public:
+ QmitkBooleanOperationsView();
+ ~QmitkBooleanOperationsView();
+
+protected:
+ void CreateQtPartControl(QWidget *parent);
+
+private slots:
+ void OnSegmentationImage1Changed(const mitk::DataNode *dataNode);
+ void OnSegmentationImage2Changed(const mitk::DataNode *dataNode);
+ void OnDifferenceButtonClicked();
+ void OnUnionButtonClicked();
+ void OnIntersectionButtonClicked();
+
+private:
+ bool CheckSegmentationImages();
+ mitk::Image::Pointer To3D(const mitk::Image::Pointer &image);
+ void AddToDataStorage(const mitk::Image::Pointer &image, const std::string &prefix) const;
+ void EnableButtons(bool enable = true);
+ void DisableButtons();
+
+ QWidget *m_Parent;
+ Ui::QmitkBooleanOperationsView m_Controls;
+};
+
+#endif
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.ui b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.ui
new file mode 100644
index 0000000000..2702257ae3
--- /dev/null
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkBooleanOperationsView.ui
@@ -0,0 +1,276 @@
+
+
+ QmitkBooleanOperationsView
+
+
+
+ 0
+ 0
+ 295
+ 374
+
+
+
+ -
+
+
+ Segmentation Images
+
+
+
-
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ QComboBox::AdjustToMinimumContentsLength
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ QComboBox::AdjustToMinimumContentsLength
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+ 200
+ 0
+ 0
+
+
+
+
+
+
+
+
+ 84
+ 82
+ 78
+
+
+
+
+
+
+ 84
+ 82
+ 78
+
+
+
+
+
+
+ 84
+ 82
+ 78
+
+
+
+
+
+
+
+
+ 50
+ false
+
+
+
+ Please select two different segmentation images above.
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 71
+ 0
+
+
+
+ Difference
+
+
+
+ :/boolean/btnDifference.png:/boolean/btnDifference.png
+
+
+ Qt::ToolButtonTextUnderIcon
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 71
+ 0
+
+
+
+ Union
+
+
+
+ :/boolean/btnUnion.png:/boolean/btnUnion.png
+
+
+ Qt::ToolButtonTextUnderIcon
+
+
+
+ -
+
+
+ false
+
+
+
+ 0
+ 0
+
+
+
+
+ 71
+ 0
+
+
+
+ Intersection
+
+
+
+ :/boolean/btnIntersection.png:/boolean/btnIntersection.png
+
+
+ Qt::ToolButtonTextUnderIcon
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 271
+
+
+
+
+
+
+
+
+ QmitkDataStorageComboBox
+ QComboBox
+ QmitkDataStorageComboBox.h
+
+
+
+
+
+
+
diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
index 9613ce7ab7..7f05e95115 100644
--- a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
+++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
@@ -1,28 +1,30 @@
#include "mitkPluginActivator.h"
#include "QmitkSegmentationView.h"
+#include "QmitkBooleanOperationsView.h"
#include "QmitkThresholdAction.h"
#include "QmitkCreatePolygonModelAction.h"
#include "QmitkStatisticsAction.h"
#include "QmitkAutocropAction.h"
#include "QmitkSegmentationPreferencePage.h"
#include "QmitkDeformableClippingPlaneView.h"
using namespace mitk;
void PluginActivator::start(ctkPluginContext *context)
{
- BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationView, context);
- BERRY_REGISTER_EXTENSION_CLASS(QmitkThresholdAction, context);
- BERRY_REGISTER_EXTENSION_CLASS(QmitkCreatePolygonModelAction, context);
- BERRY_REGISTER_EXTENSION_CLASS(QmitkStatisticsAction, context);
- BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropAction, context);
- BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationPreferencePage, context);
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationView, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkBooleanOperationsView, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkThresholdAction, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkCreatePolygonModelAction, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkStatisticsAction, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropAction, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDeformableClippingPlaneView, context)
}
void PluginActivator::stop(ctkPluginContext *)
{
}
Q_EXPORT_PLUGIN2(org_mitk_gui_qt_segmentation, mitk::PluginActivator)