diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 0c330b64bf..b41b42f5a7 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,87 +1,88 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:OFF org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF #org.blueberry.test:ON #org.blueberry.uitest:ON #Testing/org.blueberry.core.runtime.tests:ON #Testing/org.blueberry.osgi.tests:ON org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.simulation:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.simulation:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.renderwindowmanager:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.echotrack:OFF org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.multilabelsegmentation:OFF org.mitk.matchpoint.core.helper:OFF org.mitk.gui.qt.matchpoint.algorithm.browser:OFF org.mitk.gui.qt.matchpoint.algorithm.control:OFF org.mitk.gui.qt.matchpoint.algorithm.batch:OFF org.mitk.gui.qt.matchpoint.mapper:OFF org.mitk.gui.qt.matchpoint.framereg:OFF org.mitk.gui.qt.matchpoint.visualizer:OFF org.mitk.gui.qt.matchpoint.evaluator:OFF org.mitk.gui.qt.matchpoint.manipulator:OFF org.mitk.gui.qt.cest:OFF + org.mitk.gui.qt.standardplanetool:ON ) diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/CMakeLists.txt b/Plugins/org.mitk.gui.qt.standardplanetool/CMakeLists.txt new file mode 100644 index 0000000000..bdc2ed00f4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_standardplanetool) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_QT_STANDARDPLANETOOL + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt +) + diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/documentation/UserManual/StandardPlaneTool.dox b/Plugins/org.mitk.gui.qt.standardplanetool/documentation/UserManual/StandardPlaneTool.dox new file mode 100644 index 0000000000..c93bf54ca8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/documentation/UserManual/StandardPlaneTool.dox @@ -0,0 +1,4 @@ +/** +\page org_mitk_gui_qt_standardplanetool Standard Plane Tool + +*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.standardplanetool/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..83ddb2d2a1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_imagecropper org.mitk.gui.qt.imagecropper + \ingroup MITKPlugins + + \brief This is the image cropper plugin. It can crop images. + +*/ + +/** + \defgroup org_mitk_gui_qt_imagecropper_internal Internal + \ingroup org_mitk_gui_qt_imagecropper + + \brief This subcategory includes the internal classes of the org.mitk.gui.qt.imagecropper plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/files.cmake b/Plugins/org.mitk.gui.qt.standardplanetool/files.cmake new file mode 100644 index 0000000000..2483136eca --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/files.cmake @@ -0,0 +1,36 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_standardplanetool_Activator.cpp + QmitkStandardPlaneTool.cpp +) + +set(UI_FILES + src/internal/QmitkStandardPlaneToolControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_standardplanetool_Activator.h + src/internal/QmitkStandardPlaneTool.h +) + +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +#set(QRC_FILES +# resources/imagecropper.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/Plugins/org.mitk.gui.qt.standardplanetool/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.standardplanetool/manifest_headers.cmake new file mode 100644 index 0000000000..a6f7e48634 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MITK Standard Planes") +set(Plugin-Version "1.0.0") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/plugin.xml b/Plugins/org.mitk.gui.qt.standardplanetool/plugin.xml new file mode 100644 index 0000000000..892629096d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/plugin.xml @@ -0,0 +1,21 @@ + + + + + + + + + Crop images to a given size + + + + + diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/resources/icon.png b/Plugins/org.mitk.gui.qt.standardplanetool/resources/icon.png new file mode 100644 index 0000000000..0fdfa0dfd1 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.standardplanetool/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.cpp b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.cpp new file mode 100644 index 0000000000..1a7ba6bacc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.cpp @@ -0,0 +1,580 @@ + +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkStandardPlaneTool.h" + +#include "Poco/DirectoryIterator.h" + +// MITK +#include +#include +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include +#include +#include +#include "mitkPlanePositionManager.h" +#include "mitkPlanarCircle.h" +#include "mitkVtkRepresentationProperty.h" + +#include "org_mitk_gui_qt_standardplanetool_Activator.h" + + +// Qmitk +#include "QmitkStdMultiWidget.h" + +// Qt +#include +#include +#include + +// VTK (for testing evaluation methods) +#include +#include +#include + +#include +#include "vtkDoubleArray.h" +#include "vtkFloatArray.h" +#include "vtkPointData.h" +#include "vtkProperty.h" +#include +#include + + + +const std::string QmitkStandardPlaneTool::VIEW_ID = "org.mitk.views.qmitkstandardplanetool"; + +QmitkStandardPlaneTool::QmitkStandardPlaneTool(QObject *parent): +m_OldNode(nullptr), +m_WorkingNode(nullptr), +m_showSPV(0) +{ +} + +QmitkStandardPlaneTool::~QmitkStandardPlaneTool() +{ +} + +void QmitkStandardPlaneTool::CreateQtPartControl(QWidget *parent) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + + ////invalidate timer for first measurement of plane-adjustment-time (user tab) + //m_timer.invalidate(); + + // create GUI widgets from the Qt Designer's .ui file + m_Controls.patientImageSelector->SetDataStorage(this->GetDataStorage()); + m_Controls.patientImageSelector->SetPredicate(mitk::NodePredicateAnd::New( + mitk::TNodePredicateDataType::New(), + mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")))); + m_WorkingNode= m_Controls.patientImageSelector->GetSelectedNode(); + + //// create signal/slot connections of comboboxes + connect(m_Controls.patientImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), + this, SLOT(OnComboBoxSelectionChanged(const mitk::DataNode*))); + + connect(m_Controls.pB_SaveToFile, SIGNAL(clicked()), this, SLOT(SaveIntersectionFromNodeToFile())); + connect(m_Controls.pB_StandardPlaneTool, SIGNAL(clicked()), this, SLOT(ToggleStandardPlaneToolView())); + connect(m_Controls.pB_savePosition, SIGNAL(clicked()), this, SLOT(AddPositionNode())); + connect(m_Controls.pB_loadPositions, SIGNAL(clicked()), this, SLOT(LoadPositionFromNode())); + + m_Controls.gB_StandardPlaneTool->hide(); + m_Controls.patientImageSelector->setEnabled(true); +} + +void QmitkStandardPlaneTool::ToggleStandardPlaneToolView() +{ + if (!m_showSPV) + m_Controls.gB_StandardPlaneTool->show(); + else + m_Controls.gB_StandardPlaneTool->hide(); + + m_showSPV = !m_showSPV; +} + +void QmitkStandardPlaneTool::OnSelectionChanged(const mitk::DataNode* node) +{ + mitk::DataNode* selectedNode = const_cast(node); + QList nodes; + nodes.push_back(selectedNode); + //TODO because a part is needed a part is given (this should be changed to something else) + this->OnSelectionChanged(this->GetSite()->GetPart(), nodes); +} + +void QmitkStandardPlaneTool::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList &nodes) +{ + + if (!nodes.isEmpty()) + { + mitk::DataNode::Pointer referenceData = nodes.front(); + if (referenceData.IsNull()) return; + + if (m_OldNode.IsNull()) + { + m_OldNode = referenceData; + } + else if (this->GetDataStorage()->GetNamedNode(m_WorkingNode->GetName())) + { + m_OldNode = m_WorkingNode; + } + else + { + m_OldNode = referenceData; + } + m_WorkingNode = referenceData; + //set the working node to visible + m_WorkingNode->SetProperty("visible", mitk::BoolProperty::New(true)); + + //set comboBox to reference image + disconnect(m_Controls.patientImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), + this, SLOT(OnComboBoxSelectionChanged(const mitk::DataNode*))); + + m_Controls.patientImageSelector->setCurrentIndex(m_Controls.patientImageSelector->Find(referenceData)); + + connect(m_Controls.patientImageSelector, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), + this, SLOT(OnComboBoxSelectionChanged(const mitk::DataNode*))); + + + mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isPositionNode", mitk::BoolProperty::New(true)); + //load all nodes that are children of the working node in data storage + mitk::DataStorage::SetOfObjects::ConstPointer markers = this->GetDataStorage()->GetDerivations(m_WorkingNode, isMarker); + if (!markers->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter) + { + int markerId; + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + } + } + + ////check if time node exists and if not create node (start timmer) until new node is selected + ////checkbox that is activated by the user when everything is loaded and time recording starts + //if (m_Controls.checkBoxMeasureTime->isChecked()) + //{ + // int time = 0; + // if (m_timer.isValid() && (!m_OldNode->GetIntProperty("time elapsed", time) || time == 0)) m_OldNode->SetIntProperty("time elapsed", m_timer.elapsed()); + // m_timer.restart(); + //} + + } +} + +void QmitkStandardPlaneTool::OnComboBoxSelectionChanged(const mitk::DataNode* node) +{ + //if at least one node remains in the data manager + if (node != NULL) + m_Controls.patientImageSelector->setEnabled(true); + else + m_Controls.patientImageSelector->setEnabled(false); + + this->OnSelectionChanged(node); +} + + +void QmitkStandardPlaneTool::AddPositionNode() +{ + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + //we need to save all planes... + for (int i = 1; i <= 3; i++) + { + + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << i; + std::string multiWidgetString = multiWidgetStream.str(); + + mitk::BaseRenderer *m_Rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + + if (m_Rendereri) + { + const mitk::PlaneGeometry* plane = dynamic_cast< const mitk::SlicedGeometry3D*>(m_Rendereri->GetSliceNavigationController()->GetCurrentGeometry3D())->GetPlaneGeometry(0); + + //Getting Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_standardplanetool_Activator::GetContext(); + ctkServiceReference ppmRef = context->getServiceReference(); + mitk::PlanePositionManagerService* service = context->getService(ppmRef); + //unsigned int size = service->GetNumberOfPlanePositions(); + //context->ungetService(ppmRef); + + //node predicate property to identify all childnodes for planepositioning + mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isPositionNode", mitk::BoolProperty::New(true)); + //removes all nodes that are children of the working node in data storage + mitk::DataStorage::SetOfObjects::ConstPointer markers = this->GetDataStorage()->GetDerivations(m_WorkingNode, isMarker); + if (!markers->empty() && i == 1) + { + this->GetDataStorage()->Remove(markers); + //remove all entries of these nodes in the service + for (mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter) + { + int markerId; + (*iter)->GetIntProperty("Plane Position ID", markerId); + //get all position nodes in the data manager + mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isPositionNode", mitk::BoolProperty::New(true)); + mitk::DataStorage::SetOfObjects::ConstPointer positionNodes = this->GetDataStorage()->GetSubset(isMarker); + bool duplicate = false; + int duplicateId; + //iterate over the found nodes + for (unsigned int i = 0; i < positionNodes->size(); i++) //TODO make this efficient! + { + positionNodes->at(i)->GetIntProperty("Plane Position ID", duplicateId); + if (markerId == duplicateId) duplicate = true; + } + if (!duplicate) service->RemovePlanePosition(markerId); + } + } + + unsigned int id = service->AddNewPlanePosition(plane, m_Rendereri->GetSliceNavigationController()->GetSlice()->GetPos()); + + //construct node name with some property-coding + std::stringstream nodeNameStream; + nodeNameStream << "Planeposition "; + //insert name extension axial/sagittal/coronal + switch (i) + { + case 1: nodeNameStream << "axial"; + break; + case 2: nodeNameStream << "sagittal"; + break; + case 3: nodeNameStream << "coronal"; + } + + std::string nameString = nodeNameStream.str(); + + mitk::PlanarCircle::Pointer positionMarker = mitk::PlanarCircle::New(); + mitk::Point2D p1; + plane->Map(plane->GetCenter(), p1); + mitk::Point2D p2 = p1; + p2[0] -= plane->GetSpacing()[0]; + p2[1] -= plane->GetSpacing()[1]; + positionMarker->PlaceFigure(p1); + positionMarker->SetCurrentControlPoint(p1); + positionMarker->SetPlaneGeometry(const_cast(plane)); + + // the current selected node in the image selector + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + + mitk::DataNode::Pointer planePositionNode = mitk::DataNode::New(); + + planePositionNode->SetData(positionMarker); + //TODO workaround for loading the plane positions (filling the service) + planePositionNode->SetIntProperty("sliceIndex", m_Rendereri->GetSliceNavigationController()->GetSlice()->GetPos()); + //Saving the ID of the plane position as a property of the node + planePositionNode->SetIntProperty("Plane Position ID", id); + planePositionNode->SetProperty("name", mitk::StringProperty::New(nameString.c_str())); + planePositionNode->SetProperty("isPositionNode", mitk::BoolProperty::New(true)); + planePositionNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); + planePositionNode->SetBoolProperty("PlanarFigureInitializedWindow", true, m_Rendereri); + //TODO if the position nodes are set to helper object the loading does not work + planePositionNode->SetProperty("helper object", mitk::BoolProperty::New(false)); + //unchecks the planeposition nodes in datamanager + planePositionNode->SetProperty("visible", mitk::BoolProperty::New(false)); + + if (plane) + { + this->GetDataStorage()->Add(planePositionNode, imageNode); + } + } + } +} + +void QmitkStandardPlaneTool::LoadPositionNode(const mitk::DataNode *node, int id) +{ + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + QmitkRenderWindow* selectedRenderWindow = 0; + QmitkRenderWindow* RenderWindow1 = this->GetRenderWindowPart()->GetQmitkRenderWindow("axial"); + QmitkRenderWindow* RenderWindow2 = this->GetRenderWindowPart()->GetQmitkRenderWindow("sagittal"); + QmitkRenderWindow* RenderWindow3 = this->GetRenderWindowPart()->GetQmitkRenderWindow("coronal"); + + bool PlanarFigureInitializedWindow = false; + + // find initialized renderwindow + if (node->GetBoolProperty("PlanarFigureInitializedWindow", + PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) + { + selectedRenderWindow = RenderWindow1; + } + if (!selectedRenderWindow && node->GetBoolProperty( + "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, + RenderWindow2->GetRenderer())) + { + selectedRenderWindow = RenderWindow2; + } + if (!selectedRenderWindow && node->GetBoolProperty( + "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, + RenderWindow3->GetRenderer())) + { + selectedRenderWindow = RenderWindow3; + } + + if (selectedRenderWindow) + { + { + ctkPluginContext* context = mitk::org_mitk_gui_qt_standardplanetool_Activator::GetContext(); + ctkServiceReference ppmRef = context->getServiceReference(); + mitk::PlanePositionManagerService* service = context->getService(ppmRef); + selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); + context->ungetService(ppmRef); + } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } +} + +void QmitkStandardPlaneTool::ResetTimeProperty() +{ + //reset the saved time for plane adjustment of the working node + // m_WorkingNode->SetIntProperty("time elapsed", 0); +} + + +void QmitkStandardPlaneTool::LoadPositionsFromNodes() +{ + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_standardplanetool_Activator::GetContext(); + ctkServiceReference ppmRef = context->getServiceReference(); + mitk::PlanePositionManagerService* service = context->getService(ppmRef); + service->RemoveAllPlanePositions(); + + int sliceIndex = 0; + mitk::PlanarCircle::Pointer positionMarker = mitk::PlanarCircle::New(); + int id; + //get position nodes in the data manager and add them with the planepositionmanger service + mitk::DataNode::Pointer coronalPosNode = this->GetDataStorage()->GetNamedNode("Planeposition coronal"); + if (coronalPosNode != nullptr){ + coronalPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (coronalPosNode->GetData()); + const mitk::Geometry2D::ConstPointer corPlane = positionMarker->GetPlaneGeometry(); + id = service->AddNewPlanePosition(corPlane, sliceIndex); + coronalPosNode->SetIntProperty("Plane Position ID", id); + MITK_INFO << "/////////////////Marker Pointer\\\\\\\\\\\\\\\\ "; + MITK_INFO << positionMarker; + } + mitk::DataNode::Pointer axialPosNode = this->GetDataStorage()->GetNamedNode("Planeposition axial"); + if (axialPosNode != nullptr){ + + axialPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (axialPosNode->GetData()); + const mitk::Geometry2D::ConstPointer axiPlane = positionMarker->GetPlaneGeometry(); + id = service->AddNewPlanePosition(axiPlane, sliceIndex); + axialPosNode->SetIntProperty("Plane Position ID", id); + } + mitk::DataNode::Pointer sagittalPosNode = this->GetDataStorage()->GetNamedNode("Planeposition sagittal"); + if (sagittalPosNode != nullptr){ + sagittalPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (sagittalPosNode->GetData()); + const mitk::Geometry2D::ConstPointer sagPlane = positionMarker->GetPlaneGeometry(); + id = service->AddNewPlanePosition(sagPlane, sliceIndex); + sagittalPosNode->SetIntProperty("Plane Position ID", id); + } + + context->ungetService(ppmRef); +} + +void QmitkStandardPlaneTool::LoadPositionFromNode() +{ + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_standardplanetool_Activator::GetContext(); + ctkServiceReference ppmRef = context->getServiceReference(); + mitk::PlanePositionManagerService* service = context->getService(ppmRef); + + int sliceIndex = 0; + mitk::PlanarCircle::Pointer positionMarker = mitk::PlanarCircle::New(); + + mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isPositionNode", mitk::BoolProperty::New(true)); + mitk::DataStorage::SetOfObjects::ConstPointer markers; + + //load all nodes that are children of the working node in data storage + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + markers = this->GetDataStorage()->GetDerivations(imageNode, isMarker); + MITK_INFO << "------------------------------------"; + MITK_INFO << "Process Image: " << imageNode->GetName(); + + if (!markers->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter) + { + MITK_INFO << "Marker" << std::endl; + int markerId; + std::string nodeName = (*iter)->GetName(); + //get position nodes in the data manager and add them with the planepositionmanger service + if (nodeName == "Planeposition coronal") + { + mitk::DataNode::Pointer coronalPosNode = (*iter); + coronalPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (coronalPosNode->GetData()); + mitk::PlaneGeometry::ConstPointer corPlane = positionMarker->GetPlaneGeometry(); + markerId = service->AddNewPlanePosition(corPlane, sliceIndex); + coronalPosNode->SetIntProperty("Plane Position ID", markerId); + } + else if (nodeName == "Planeposition axial") + { + mitk::DataNode::Pointer axialPosNode = (*iter); + axialPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (axialPosNode->GetData()); + mitk::PlaneGeometry::ConstPointer axiPlane = positionMarker->GetPlaneGeometry(); + markerId = service->AddNewPlanePosition(axiPlane, sliceIndex); + axialPosNode->SetIntProperty("Plane Position ID", markerId); + } + else if (nodeName == "Planeposition sagittal") + { + mitk::DataNode::Pointer sagittalPosNode = (*iter); + sagittalPosNode->GetIntProperty("sliceIndex", sliceIndex); + positionMarker = dynamic_cast (sagittalPosNode->GetData()); + mitk::PlaneGeometry::ConstPointer sagPlane = positionMarker->GetPlaneGeometry(); + markerId = service->AddNewPlanePosition(sagPlane, sliceIndex); + sagittalPosNode->SetIntProperty("Plane Position ID", markerId); + } + + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } + +} + +void QmitkStandardPlaneTool::SaveIntersectionFromNodeToFile() +{ + //get BaseRenderer for the three RenderWindows (sagittal, coronal, axial) + mitk::BaseRenderer::Pointer rendererAxi = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")); + mitk::BaseRenderer::Pointer rendererSag = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")); + mitk::BaseRenderer::Pointer rendererCor = mitk::BaseRenderer::GetInstance(mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")); + mitk::PlaneGeometry::ConstPointer sagPlane = rendererSag->GetSliceNavigationController()->GetCurrentPlaneGeometry(); + mitk::PlaneGeometry::ConstPointer corPlane = rendererCor->GetSliceNavigationController()->GetCurrentPlaneGeometry(); + mitk::PlaneGeometry::ConstPointer axiPlane = rendererAxi->GetSliceNavigationController()->GetCurrentPlaneGeometry(); + + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + std::string saveToMpsString = "C:/Users/thomass/Desktop/" + imageNode->GetName(); + + mitk::Line3D intersectionLine; + sagPlane->IntersectionLine(corPlane, intersectionLine); + + mitk::Point3D newPoint, tempPoint1, tempPoint2; + tempPoint1 = intersectionLine.GetPoint1(); + tempPoint2 = intersectionLine.GetPoint2(); + + newPoint[0] = (tempPoint1[0] - tempPoint2[0]) * 300; + newPoint[1] = (tempPoint1[1] - tempPoint2[1]) * 300; + newPoint[2] = (tempPoint1[2] - tempPoint2[2]) * 300; + + tempPoint1[0] = tempPoint1[0] + newPoint[0]; + tempPoint1[1] = tempPoint1[1] + newPoint[1]; + tempPoint1[2] = tempPoint1[2] + newPoint[2]; + + tempPoint2[0] = tempPoint2[0] - newPoint[0]; + tempPoint2[1] = tempPoint2[1] - newPoint[1]; + tempPoint2[2] = tempPoint2[2] - newPoint[2]; + + mitk::PointSet::Pointer intersectionSagCorPointSet = mitk::PointSet::New(); + intersectionSagCorPointSet->InsertPoint(0, tempPoint1); + intersectionSagCorPointSet->InsertPoint(1, tempPoint2); + + mitk::DataNode::Pointer intersectionSagCorPointNode = mitk::DataNode::New(); + intersectionSagCorPointNode->SetData(intersectionSagCorPointSet); + intersectionSagCorPointNode->SetName("intersection sag/cor"); + // activate property for rendering lines between the points + intersectionSagCorPointNode->SetProperty("show contour", mitk::BoolProperty::New(true)); + + mitk::IOUtil::SavePointSet(intersectionSagCorPointSet, (saveToMpsString + "_line1.mps")); + + + + sagPlane->IntersectionLine(axiPlane, intersectionLine); + + tempPoint1 = intersectionLine.GetPoint1(); + tempPoint2 = intersectionLine.GetPoint2(); + + newPoint[0] = (tempPoint1[0] - tempPoint2[0]) * 300; + newPoint[1] = (tempPoint1[1] - tempPoint2[1]) * 300; + newPoint[2] = (tempPoint1[2] - tempPoint2[2]) * 300; + + tempPoint1[0] = tempPoint1[0] + newPoint[0]; + tempPoint1[1] = tempPoint1[1] + newPoint[1]; + tempPoint1[2] = tempPoint1[2] + newPoint[2]; + + tempPoint2[0] = tempPoint2[0] - newPoint[0]; + tempPoint2[1] = tempPoint2[1] - newPoint[1]; + tempPoint2[2] = tempPoint2[2] - newPoint[2]; + + mitk::PointSet::Pointer intersectionSagAxiPointSet = mitk::PointSet::New(); + intersectionSagAxiPointSet->InsertPoint(0, tempPoint1); + intersectionSagAxiPointSet->InsertPoint(1, tempPoint2); + + mitk::DataNode::Pointer intersectionSagAxiPointNode = mitk::DataNode::New(); + intersectionSagAxiPointNode->SetData(intersectionSagAxiPointSet); + intersectionSagAxiPointNode->SetName("intersection sag/axi"); + // activate property for rendering lines between the points + intersectionSagAxiPointNode->SetProperty("show contour", mitk::BoolProperty::New(true)); + + mitk::IOUtil::SavePointSet(intersectionSagAxiPointSet, (saveToMpsString + "_line2.mps")); + + + + corPlane->IntersectionLine(axiPlane, intersectionLine); + + tempPoint1 = intersectionLine.GetPoint1(); + tempPoint2 = intersectionLine.GetPoint2(); + //tempPoint1 = (tempPoint1-tempPoint2)*10; + newPoint[0] = (tempPoint1[0] - tempPoint2[0]) * 300; + newPoint[1] = (tempPoint1[1] - tempPoint2[1]) * 300; + newPoint[2] = (tempPoint1[2] - tempPoint2[2]) * 300; + + tempPoint1[0] = tempPoint1[0] + newPoint[0]; + tempPoint1[1] = tempPoint1[1] + newPoint[1]; + tempPoint1[2] = tempPoint1[2] + newPoint[2]; + + tempPoint2[0] = tempPoint2[0] - newPoint[0]; + tempPoint2[1] = tempPoint2[1] - newPoint[1]; + tempPoint2[2] = tempPoint2[2] - newPoint[2]; + + mitk::PointSet::Pointer intersectionCorAxiPointSet = mitk::PointSet::New(); + intersectionCorAxiPointSet->InsertPoint(0, tempPoint1); + intersectionCorAxiPointSet->InsertPoint(1, tempPoint2); + + mitk::DataNode::Pointer intersectionCorAxiPointNode = mitk::DataNode::New(); + intersectionCorAxiPointNode->SetData(intersectionCorAxiPointSet); + intersectionCorAxiPointNode->SetName("intersection cor/axi"); + // activate property for rendering lines between the points + intersectionCorAxiPointNode->SetProperty("show contour", mitk::BoolProperty::New(true)); + + mitk::IOUtil::SavePointSet(intersectionCorAxiPointSet, (saveToMpsString + "_line3.mps")); +} + + +void QmitkStandardPlaneTool::SetFocus() +{ +} + + diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.h b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.h new file mode 100644 index 0000000000..3189c2e25c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneTool.h @@ -0,0 +1,132 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +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 QmitkStandardPlaneTool_h +#define QmitkStandardPlaneTool_h + +#include + +#ifdef WIN32 +#pragma warning( disable : 4250 ) +#endif + +#include +#include "QVTKWidget.h" +#include "QmitkRegisterClasses.h" + +#include "itkCommand.h" +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "usServiceRegistration.h" + +#include + +// QT +#include + +#include "ui_QmitkStandardPlaneToolControls.h" + +class QmitkPointListWidget; + +/*! +@brief QmitkImageCropperView +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + +\sa QmitkFunctionality +\ingroup ${plugin_target}_internal +*/ +class QmitkStandardPlaneTool : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) +private: + + Q_OBJECT + +public: + + QmitkStandardPlaneTool(QObject *parent = 0); + + virtual ~QmitkStandardPlaneTool(); + + static const std::string VIEW_ID; + + virtual void CreateQtPartControl(QWidget *parent); + + + ///// \brief Handles selection of data nodes + virtual void OnSelectionChanged(const mitk::DataNode* node); + ///// \brief Handles selection of data nodes + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList &nodes); + + protected slots: + + /// \brief Handles selection of images through the comboboxes + void OnComboBoxSelectionChanged(const mitk::DataNode* node); + /// \brief Handles selection of images through the comboboxes + //void OnAtlasComboBoxSelectionChanged(const mitk::DataNode* node); + + /// \brief Called for resetting the recorded time in the workingNode (reference data acquisition) + void ResetTimeProperty(); + /// \brief Called for saving the position of the planes (e.g. for saving reference data) + void AddPositionNode(); + + /// \brief Load the position information from the position nodes after loading an MITK project + void LoadPositionsFromNodes(); + /// \brief Load the position information from the selected position node + void LoadPositionFromNode(); + + /// \brief Show or hide tool view + void ToggleStandardPlaneToolView(); + + /// \brief Calculate and save intersection lines between the planes to file + void SaveIntersectionFromNodeToFile(); + +protected: + + /// \brief Called for loading the plane position from a data node + void LoadPositionNode(const mitk::DataNode *node, int id); + + + /// \brief Old data node selection (used for memory of last selected node) + mitk::DataNode::Pointer m_OldNode; + /// \brief the current selected data node + mitk::DataNode::Pointer m_WorkingNode; + + bool m_showSPV; + virtual void SetFocus(); + + + Ui::QmitkStandardPlaneToolControls m_Controls; + + +}; + + +#endif // QmitkStandardPlaneTool_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneToolControls.ui b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneToolControls.ui new file mode 100644 index 0000000000..e91004088a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/QmitkStandardPlaneToolControls.ui @@ -0,0 +1,155 @@ + + + QmitkStandardPlaneToolControls + + + + 0 + 0 + 290 + 790 + + + + + 0 + 0 + + + + + 290 + 790 + + + + + 16777215 + 16777215 + + + + QmitkTemplate + + + + + 10 + 130 + 251 + 161 + + + + + 0 + 0 + + + + Standard Plane Tool + + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + Images + + + Qt::AlignCenter + + + + + + + + + + + Set New Position + + + + + + + Load Current Position + + + + + + + Save All Positionsnodes To File + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 20 + 20 + 71 + 71 + + + + Standard + Plane + Tool + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.cpp b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.cpp new file mode 100644 index 0000000000..6a2b51a4e3 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.cpp @@ -0,0 +1,51 @@ +/*========================================================================= + +Program: Medical Imaging & Interaction Toolkit +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 "org_mitk_gui_qt_standardplanetool_Activator.h" + +#include + +#include "QmitkStandardPlaneTool.h" +#include +#include + +US_INITIALIZE_MODULE + +namespace mitk { + ctkPluginContext* org_mitk_gui_qt_standardplanetool_Activator::m_Context = 0; + + void org_mitk_gui_qt_standardplanetool_Activator::start(ctkPluginContext* context) + { +// RegisterBoundingShapeObjectFactory(); + BERRY_REGISTER_EXTENSION_CLASS(QmitkStandardPlaneTool, context) + m_Context = context; + } + + void org_mitk_gui_qt_standardplanetool_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context) + } + + ctkPluginContext* org_mitk_gui_qt_standardplanetool_Activator::GetContext() + { + return m_Context; + } +} + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +Q_EXPORT_PLUGIN2(org_mitk_gui_qt_standardplanetool, mitk::PluginActivator) +#endif \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.h b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.h new file mode 100644 index 0000000000..bb6bda0032 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.standardplanetool/src/internal/org_mitk_gui_qt_standardplanetool_Activator.h @@ -0,0 +1,48 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ +#ifndef org_mitk_gui_qt_standardplanetool_Activator_h +#define org_mitk_gui_qt_standardplanetool_Activator_h + +#include + +namespace mitk { + + class org_mitk_gui_qt_standardplanetool_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_standardplanetool") +#endif + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context) override; + void stop(ctkPluginContext* context) override; + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // PluginActivator + +} + +#endif // org_mitk_gui_qt_standardplanetool_Activator_h