diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 0c330b64bf..111e778b12 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.shapemodelutil:ON ) diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/UserManual/ShapeModelUtil.dox b/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/UserManual/ShapeModelUtil.dox new file mode 100644 index 0000000000..0ff6e95d7a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/UserManual/ShapeModelUtil.dox @@ -0,0 +1,4 @@ +/** +\page org_mitk_gui_qt_shapemodelutil Shape Model Util + +*/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..d38508d37e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/documentation/doxygen/modules.dox @@ -0,0 +1,7 @@ +/** + \defgroup org_mitk_gui_qt_shapemodelutil org.mitk.gui.qt.shapemodelutil + \ingroup MITKPlugins + + \brief This plugin is used to prepare image and segmentation data for shape model segmentation + +*/ diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/files.cmake b/Plugins/org.mitk.gui.qt.shapemodelutil/files.cmake new file mode 100644 index 0000000000..defb5696f2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/files.cmake @@ -0,0 +1,40 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_shapemodelutil_Activator.cpp + QmitkShapeModelUtil.cpp + mitkUpperAnkleCropper.cpp +# QmitkShapeModelHelperFunctions.cpp +) + +set(UI_FILES + src/internal/QmitkShapeModelUtilControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_shapemodelutil_Activator.h + src/internal/QmitkShapeModelUtil.h + src/internal/mitkUpperAnkleCropper.h +# src/internal/ QmitkShapeModelHelperFunctions.h +) + +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +#set(QRC_FILES +# resources/shapemodelutil.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.shapemodelutil/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.shapemodelutil/manifest_headers.cmake new file mode 100644 index 0000000000..d9bf0d3cd5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MITK Shape Model Util") +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.shapemodelutil/plugin.xml b/Plugins/org.mitk.gui.qt.shapemodelutil/plugin.xml new file mode 100644 index 0000000000..a59f02677c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/plugin.xml @@ -0,0 +1,21 @@ + + + + + + + + + Crop images to a given size + + + + + diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/resources/icon.png b/Plugins/org.mitk.gui.qt.shapemodelutil/resources/icon.png new file mode 100644 index 0000000000..0fdfa0dfd1 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.shapemodelutil/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkCutWidgetControls.ui b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkCutWidgetControls.ui new file mode 100644 index 0000000000..5493bfb5ee --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkCutWidgetControls.ui @@ -0,0 +1,90 @@ + + + QmitkShapeModelUtilControls + + + + 0 + 0 + 290 + 790 + + + + + 0 + 0 + + + + + 290 + 790 + + + + + 16777215 + 16777215 + + + + QmitkTemplate + + + + + 10 + 180 + 251 + 101 + + + + + 0 + 0 + + + + Cut Masks + + + + + + + + Cut Image + + + + + + + Cut All and Save + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.cpp b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.cpp new file mode 100644 index 0000000000..a48c62df93 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.cpp @@ -0,0 +1,1095 @@ + +#include "Poco/DirectoryIterator.h" + +// MITK +#include "mitkPlanePositionManager.h" +#include "usModuleContext.h" +#include "usServiceReference.h" +#include "usGetModuleContext.h" + +#include "mitkPlanarCircle.h" +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include + +#include //Eval +#include +#include "mitkApplyTransformMatrixOperation.h" +#include "mitkInteractionConst.h" +#include +#include +#include + +// MITK (Eval) +#include "mitkSceneIO.h" +#include + +// Qmitk +#include "QmitkStdMultiWidgetEditor.h" + +// Qt +#include +#include +#include + +// VTK (for testing evaluation methods) +#include +#include +#include + +#include +#include +#include +#include + +//#include +//#include +//#include +//#include +//#include + +//#include "mitkManualSegmentationToSurfaceFilter.h" + +#include "vtkFloatArray.h" +#include "vtkDoubleArray.h" +#include "vtkPointData.h" +#include "mitkLookupTableProperty.h" +#include "mitkVtkRepresentationProperty.h" +#include "vtkProperty.h" +#include +//#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + +#include +#include + +#include +#include +#include + + +// ------------------------ +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#include "itkScalarToRGBPixelFunctor.h" +#include "itkUnaryFunctorImageFilter.h" +#include "itkVectorCastImageFilter.h" +#include "itkVectorGradientAnisotropicDiffusionImageFilter.h" +#include "itkWatershedImageFilter.h" +#include "itkRescaleIntensityImageFilter.h" +#include "itkScalarToRGBColormapImageFilter.h" +#include "itkGradientMagnitudeImageFilter.h" +#include "itkCenteredRigid2DTransform.h" +//--------------------------- +// Sarina +#include "vtkLandmarkTransform.h" +#include + +#include "mitkImageToItk.h" +#include "mitkImageAccessByItk.h" +#include "mitkSegToSurface.h" +#include "mitkImageSliceSelector.h" + +#include "itkUpperAnkleJointSegmentation.h" +#include "mitkCalcaneusUtils.h" + + +//------- +// Registration +#include +#include +#include +#include + +#include "itkMutualInformationImageToImageMetric.h" +#include +#include "itkCommand.h" + +#include +#include +#include +#include + +#include "itkImageRegistrationMethod.h" +#include "itkTranslationTransform.h" +#include "itkMutualInformationImageToImageMetric.h" +#include "itkGradientDescentOptimizer.h" +#include "itkNormalizeImageFilter.h" +#include "itkDiscreteGaussianImageFilter.h" +#include "itkResampleImageFilter.h" +#include "itkCastImageFilter.h" +#include "itkCheckerBoardImageFilter.h" +#include "itkEllipseSpatialObject.h" +#include "itkSpatialObjectToImageFilter.h" +#include "itkImageFileWriter.h" +#include + +#include +#include +// Seg To Surface +// Seg to Surface Filter +#include "mitkImageToSurfaceFilter.h" +#include "mitkMeshUtil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mitkUpperAnkleCropper.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + +////////////////// +void QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::ResetTimeProperty() +{ + //reset the saved time for plane adjustment of the working node + // m_WorkingNode->SetIntProperty("time elapsed", 0); +} + + +void QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::LoadPositionFromFile() +{ + + QString fileName = QFileDialog::getOpenFileName(NULL, + tr("Open Scene File with Positions"), 0, tr("MITK scene file (*.mitk)")); + + MITK_INFO << fileName; + + mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); + mitk::DataStorage::Pointer dataStorage = sceneIO->LoadScene(fileName.toStdString(), 0, true); + + + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_shapemodelutil_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 = dataStorage->GetSubset(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); + this->GetDataStorage()->Add(coronalPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(axialPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(sagittalPosNode, imageNode); + } + + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +void SaveIntersectionFromNodeToFile(mitk::DataNode::Pointer imageNode) +{ + //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")); +} + + +///////////////// + +/***************************************NORMALIZE *********************************************************************/ +void NormalizeAll(mitk::DataStorage::Pointer datastorage) +{ + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + Normalize(image); + + // Cast to MITK + + } + } + } +} + + +void Normalize(mitk::Image::Pointer image) +{ + if (image!=nullptr) + { + itk::Image::Pointer itkImage; + mitk::CastToItkImage(image, itkImage); + + typedef itk::Image FloatImageType; + typedef itk::NormalizeImageFilter< itk::Image, FloatImageType > + NormalizeFilterType; + NormalizeFilterType::Pointer normalizeFilter = NormalizeFilterType::New(); + normalizeFilter->SetInput(itkImage); + normalizeFilter->Update(); + + // Cast to MITK + } +} +/***************************************END NORMALIZE *********************************************************************/ +/********************************************************************************************************************** / + + +/***************************************CUT****************************************************************************/ +bool GetAxisPositions(mitk::DataNode::Pointer node) +{ + //get the planePositionManager Service + us::ServiceReference ppmRef = us::GetModuleContext()->GetServiceReference(); + mitk::PlanePositionManagerService* service = us::GetModuleContext()->GetService(ppmRef); + service->RemoveAllPlanePositions(); + + 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 + markers = this->GetDataStorage()->GetDerivations(node, isMarker); + (node)->SetVisibility(true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); + + 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); + } + + // mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + for (int i = 1; i <= 3; i++) + { + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << i; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + } + return true; + } + return false; +} + + +void CutAllAnkles(mitk::DataStorage::Pointer datastorage, int axis, double offset) +{ + MITK_INFO << "Cut all images"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + GetAxisPositions(dataNode, -1); + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + // get axial render window and corresponding plane + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << 1; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + + if (!rendereri) + return; + + const mitk::PlaneGeometry* plane = dynamic_cast(rendereri->GetCurrentWorldPlaneGeometry()); + mitk::PlaneGeometry::Pointer newAxiPlane = mitk::PlaneGeometry::New(); + //mitk::PlaneGeometry* newAxiPlane = mitk::PlaneGeometry::New(); + newAxiPlane = plane->Clone(); + mitk::Vector3D normal = newAxiPlane->GetNormal(); + newAxiPlane->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); // normal already in world cords?! + newAxiPlane->Translate(normal * -offset); + + try + { + mitk::Image::Pointer tibia = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Tibia.nrrd"); + auto croppedImageNode = mitk::DataNode::New(); + auto cutter = mitk::UpperAnkleCropper::New(); + cutter->SetPlane(newAxiPlane); + + // adjustable in advanced settings + cutter->SetUsePositiveDirection(false); + cutter->SetInput(tibia); + // do the actual cutting + try + { + cutter->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + mitk::IOUtil::SaveImage(cutter->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Tibia.nrrd"); + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Tibia.nrrd" + " does not exist"; + } + + + + try + { + mitk::Image::Pointer fibula = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Fibula.nrrd"); + + auto cutter2 = mitk::UpperAnkleCropper::New(); + cutter2->SetPlane(newAxiPlane); + + + cutter2->SetUsePositiveDirection(false); + cutter2->SetInput(fibula); + // do the actual cutting + try + { + cutter2->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + + mitk::IOUtil::SaveImage(cutter2->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Fibula.nrrd"); + + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Fibula.nrrd" + " does not exist"; + } + } + } + + } +} + + +void CutAnkle(mitk::DataStorage::Pointer datastorage, int axis, double offset) +{ + MITK_INFO << "Cut all images"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + GetAxisPositions(dataNode, -1); + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + // get axial render window and corresponding plane + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << 1; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + + if (!rendereri) + return; + + const mitk::PlaneGeometry* plane = dynamic_cast(rendereri->GetCurrentWorldPlaneGeometry()); + mitk::PlaneGeometry::Pointer newAxiPlane = mitk::PlaneGeometry::New(); + //mitk::PlaneGeometry* newAxiPlane = mitk::PlaneGeometry::New(); + newAxiPlane = plane->Clone(); + mitk::Vector3D normal = newAxiPlane->GetNormal(); + newAxiPlane->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); // normal already in world cords?! + newAxiPlane->Translate(normal * -offset); + + try + { + mitk::Image::Pointer tibia = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Tibia.nrrd"); + auto croppedImageNode = mitk::DataNode::New(); + auto cutter = mitk::UpperAnkleCropper::New(); + cutter->SetPlane(newAxiPlane); + + // adjustable in advanced settings + cutter->SetUsePositiveDirection(false); + cutter->SetInput(tibia); + // do the actual cutting + try + { + cutter->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + mitk::IOUtil::SaveImage(cutter->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Tibia.nrrd"); + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Tibia.nrrd" + " does not exist"; + } + + + + try + { + mitk::Image::Pointer fibula = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Fibula.nrrd"); + + auto cutter2 = mitk::UpperAnkleCropper::New(); + cutter2->SetPlane(newAxiPlane); + + + cutter2->SetUsePositiveDirection(false); + cutter2->SetInput(fibula); + // do the actual cutting + try + { + cutter2->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + + mitk::IOUtil::SaveImage(cutter2->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Fibula.nrrd"); + + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Fibula.nrrd" + " does not exist"; + } + } + } + + } +} + + +/*************************************** END CUT *********************************************************************/ +/**********************************************************************************************************************/ + +/***************************************MIRROR****************************************************************************/ + +// Flip +#include +typedef itk::Image ImageType; // TODO: change to support other datatypes +typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; + +void FlipAll(mitk::DataStorage::Pointer datastorage) +{ +mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); +mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + +if (!images->empty()) +{ + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + FlipImage(0, image); + + } + } +} + +void FlipImage(int axis, mitk::Image::Pointer image) +{ + if (image!=nullptr) + { + if (mitkImage.IsNull()) + return; + + auto flipMatrix = vtkSmartPointer::New(); + flipMatrix->Identity(); + switch (axis) + { + case 0: + flipMatrix->SetElement(0, 0, -1); + break; + case 1: + flipMatrix->SetElement(1, 1, -1); + break; + case 2: + flipMatrix->SetElement(2, 2, -1); + break; + } + + auto flipTransform = vtkSmartPointer::New(); + flipTransform->SetMatrix(flipMatrix); + flipTransform->Concatenate(mitkImage->GetGeometry()->GetVtkMatrix()); + flipTransform->Update(); + mitkImage->GetGeometry()->SetIndexToWorldTransformByVtkMatrixWithoutChangingSpacing(flipTransform->GetMatrix()); + + // ITK Flip + // // Flip image + // FlipImageFilterType::Pointer flipper = FlipImageFilterType::New(); + // flipper->SetInput(image); + // int param1 = 0; + // itk::FixedArray flipAxes; + // for (int i = 0; i<3; ++i) + // { + // if (i == param1) + // { + // flipAxes[i] = true; + // } + // else + // { + // flipAxes[i] = false; + // } + // } + // flipper->SetFlipAxes(flipAxes); + // flipper->UpdateLargestPossibleRegion(); + // mitkImage = mitk::ImportItkImage(flipper->GetOutput())->Clone(); + // std::cout << "Image flipping successful." << std::endl; + // + } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + mitk::IOUtil::SaveImage(image, "C:/Users/thomass.AD/Desktop/Test/" + dataNode->GetName() + ".nrrd"); + +} + +/*************************************** END MIRROR *********************************************************************/ +/********************************************************************************************************************** / + + +/*************************************** REGISTER ****************************************************************************/ +// Center of Mass Tibia Fibula Talus +// Landmark Registration + +/*************************************** END REGISTER *********************************************************************/ +/********************************************************************************************************************** / + + + +/*************************************** SCRIPT ****************************************************************************/ +// Names +// ID + + +/*************************************** END SCRIPT *********************************************************************/ +/********************************************************************************************************************** / diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.h b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.h new file mode 100644 index 0000000000..bbf977e425 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelHelperFunctions.h @@ -0,0 +1,172 @@ +// MITK +#include "mitkPlanePositionManager.h" +#include "usModuleContext.h" +#include "usServiceReference.h" +#include "usGetModuleContext.h" + +#include "mitkPlanarCircle.h" +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include + +#include //Eval +#include +#include "mitkApplyTransformMatrixOperation.h" +#include "mitkInteractionConst.h" + +#include + +// MITK (Eval) +#include "mitkSceneIO.h" +#include + +// Qt +#include +#include +#include + +// VTK (for testing evaluation methods) +#include +#include +#include +#include +#include +#include +#include +#include "vtkFloatArray.h" +#include "vtkDoubleArray.h" +#include "vtkPointData.h" +#include "mitkLookupTableProperty.h" +#include "mitkVtkRepresentationProperty.h" +#include "vtkProperty.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vtkLandmarkTransform.h" +#include + +// ------------------------ +#include "itkImageRegistrationMethod.h" +#include "itkTranslationTransform.h" +#include "itkNormalizeImageFilter.h" +#include "itkResampleImageFilter.h" +#include "itkCastImageFilter.h" +#include "itkImageFileWriter.h" +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#include "itkVectorCastImageFilter.h" + + + + +#include "mitkImageToItk.h" +#include "mitkImageAccessByItk.h" + + +#include "itkCommand.h" + +#include +#include +#include +#include + + +#include +#include +// Seg To Surface +// Seg to Surface Filter +#include "mitkImageToSurfaceFilter.h" +#include "mitkMeshUtil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +/***************************************NORMALIZE *********************************************************************/ +void NormalizeAll(mitk::DataStorage::Pointer datastorage) +void Normalize(mitk::Image::Pointer image) + +/***************************************END NORMALIZE *********************************************************************/ +/********************************************************************************************************************** / + + +/***************************************CUT****************************************************************************/ +bool GetAxisPositions(mitk::DataNode::Pointer node) +void CutAllAnkles(mitk::DataStorage::Pointer datastorage, int axis, double offset) +void CutAnkle(mitk::DataStorage::Pointer datastorage, int axis, double offset) + + +/*************************************** END CUT *********************************************************************/ +/**********************************************************************************************************************/ + +/***************************************MIRROR****************************************************************************/ + +// Flip +#include +typedef itk::Image ImageType; // TODO: change to support other datatypes +typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; + +void FlipAll(mitk::DataStorage::Pointer datastorage) +void FlipImage(int axis, mitk::Image::Pointer image) + + +/*************************************** END MIRROR *********************************************************************/ +/********************************************************************************************************************** / + + +/*************************************** REGISTER ****************************************************************************/ +// Center of Mass Tibia Fibula Talus +// Landmark Registration + +/*************************************** END REGISTER *********************************************************************/ +/********************************************************************************************************************** / + + + +/*************************************** SCRIPT ****************************************************************************/ +// Names +// ID + + +/*************************************** END SCRIPT *********************************************************************/ +/********************************************************************************************************************** / diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.cpp b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.cpp new file mode 100644 index 0000000000..b7a21b4986 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.cpp @@ -0,0 +1,1401 @@ + +/*=================================================================== + +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 "QmitkShapeModelUtil.h" + +#include "Poco/DirectoryIterator.h" +#include + +// MITK +#include +#include +#include +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include +#include +#include +#include "mitkPlanePositionManager.h" +#include "mitkPlanarCircle.h" +#include +#include "mitkVtkRepresentationProperty.h" +#include "itkCastImageFilter.h" + +#include "org_mitk_gui_qt_shapemodelutil_Activator.h" + + +// Qmitk +#include "QmitkStdMultiWidget.h" + +// Qt +#include +#include +#include + +// VTK (for testing evaluation methods) +#include +#include "QmitkShapeModelUtil.h" + +#include "Poco/DirectoryIterator.h" + +// MITK +#include +#include +#include +#include +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include +#include +#include +#include "mitkPlanePositionManager.h" +#include "mitkPlanarCircle.h" +#include +#include "mitkVtkRepresentationProperty.h" +#include +#include "mitkImageToSurfaceFilter.h" +#include + +#include "org_mitk_gui_qt_shapemodelutil_Activator.h" + + +// Qmitk +#include "QmitkStdMultiWidget.h" + +// Qt +#include +#include +#include + +// VTK (for testing evaluation methods) +#include +#include +#include +#include +#include +#include "vtkDoubleArray.h" +#include "vtkFloatArray.h" +#include "vtkPointData.h" +#include "vtkProperty.h" +#include +#include +#include + +#include "mitkUpperAnkleCropper.h" +mitk::Image::Pointer Normalize(mitk::Image::Pointer image); +void NormalizeAll(mitk::DataStorage::Pointer datastorage); + +const std::string QmitkShapeModelUtil::VIEW_ID = "org.mitk.views.qmitkshapemodelutil"; + +QmitkShapeModelUtil::QmitkShapeModelUtil(QObject *parent) : +m_OldNode(nullptr), +m_WorkingNode(nullptr), +m_showSPV(0), +m_WorkingDirectory("C:/Users/thomass.AD/Desktop/") +{ +} + +QmitkShapeModelUtil::~QmitkShapeModelUtil() +{ +} + +void QmitkShapeModelUtil::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.toolBox->pB_StandardPlaneTool, SIGNAL(clicked()), this, SLOT(ToggleShapeModelUtilView())); + connect(m_Controls.pB_savePosition, SIGNAL(clicked()), this, SLOT(AddPositionNode())); + connect(m_Controls.pB_loadPositions, SIGNAL(clicked()), this, SLOT(LoadPositionFromNode())); + connect(m_Controls.pB_LoadFromFile, SIGNAL(clicked()), this, SLOT(LoadPositionFromFile())); + // m_Controls.gB_StandardPlaneTool->hide(); + m_Controls.patientImageSelector->setEnabled(true); + + + connect(m_Controls.pB_MirrorImage, SIGNAL(clicked()), this, SLOT(OnMirrorClicked())); + connect(m_Controls.pB_MirrorAndSave, SIGNAL(clicked()), this, SLOT(OnMirrorAllClicked())); + connect(m_Controls.pB_NormalizeImage, SIGNAL(clicked()), this, SLOT(OnNormalizeClicked())); + connect(m_Controls.pB_NormalizeAndSave, SIGNAL(clicked()), this, SLOT(OnNormalizeAllClicked())); + connect(m_Controls.pB_CutImage, SIGNAL(clicked()), this, SLOT(OnCutClicked())); + connect(m_Controls.pB_CutAndSave, SIGNAL(clicked()), this, SLOT(OnCutAllClicked())); + connect(m_Controls.pB_ApplyRegistration, SIGNAL(clicked()), this, SLOT(OnRegistrationClicked())); + connect(m_Controls.pB_ChangeDir, SIGNAL(clicked()), this, SLOT(OnChangeFolderClicked())); + connect(m_Controls.pB_CreateSkripts, SIGNAL(clicked()), this, SLOT(OnScriptAllClicked())); + + m_Controls.labelDir->setText(m_WorkingDirectory.mid(1,20)); + +} + + +//void ScriptAll(mitk::DataStorage::Pointer datastorage); + +void QmitkShapeModelUtil::OnMirrorClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); +} +void QmitkShapeModelUtil::OnMirrorAllClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); +} + +void QmitkShapeModelUtil::OnNormalizeClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + mitk::Image::Pointer image = dynamic_cast(imageNode->GetData()); + imageNode->SetData(Normalize(image)); + + // Reinit node + mitk::RenderingManager::GetInstance()->InitializeViews( + imageNode->GetData()->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + +} + + +void QmitkShapeModelUtil::OnNormalizeAllClicked() +{ + + NormalizeAll(this->GetDataStorage()); +} + +void QmitkShapeModelUtil::OnCutClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + CutAnkle(this->GetDataStorage(), 1, -80); +} + +void QmitkShapeModelUtil::OnCutAllClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + CutAllAnkles(this->GetDataStorage(), 1, -80); + // Reinit node + mitk::RenderingManager::GetInstance()->InitializeViews( + imageNode->GetData()->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + +} + +void QmitkShapeModelUtil::OnRegistrationClicked() +{ + mitk::DataNode* imageNode(m_Controls.patientImageSelector->GetSelectedNode()); + RegisterAll(this->GetDataStorage(), imageNode); +} + +void QmitkShapeModelUtil::OnChangeFolderClicked() +{ + QString dir = QFileDialog::getExistingDirectory(nullptr, tr("Open Directory"),"/home", + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + m_Controls.labelDir->setText(dir); + m_WorkingDirectory = dir; +} + +void QmitkShapeModelUtil::OnScriptAllClicked() +{ + ScriptAll(this->GetDataStorage()); +} + +void QmitkShapeModelUtil::ToggleShapeModelUtilView() +{ + if (!m_showSPV) + m_Controls.gB_StandardPlaneTool->show(); + else + m_Controls.gB_StandardPlaneTool->hide(); + + m_showSPV = !m_showSPV; +} + +void QmitkShapeModelUtil::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 QmitkShapeModelUtil::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 QmitkShapeModelUtil::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 QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::ResetTimeProperty() +{ + //reset the saved time for plane adjustment of the working node + // m_WorkingNode->SetIntProperty("time elapsed", 0); +} + + +void QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::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_shapemodelutil_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 QmitkShapeModelUtil::LoadPositionFromFile() +{ + + QString fileName = QFileDialog::getOpenFileName(NULL, + tr("Open Scene File with Positions"), 0, tr("MITK scene file (*.mitk)")); + + MITK_INFO << fileName; + + mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); + mitk::DataStorage::Pointer dataStorage = sceneIO->LoadScene(fileName.toStdString(), 0, true); + + + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_shapemodelutil_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 = dataStorage->GetSubset(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); + this->GetDataStorage()->Add(coronalPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(axialPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(sagittalPosNode, imageNode); + } + + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +void QmitkShapeModelUtil::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 QmitkShapeModelUtil::SetFocus() +{ +} + + +//// --------------------------------- Util Functions ----------------------------------------------// +// +// +/////////////////// +// +///***************************************NORMALIZE *********************************************************************/ +mitk::Image::Pointer Normalize(mitk::Image::Pointer image) +{ + if (image != nullptr) + { + itk::Image::Pointer itkImage; + mitk::CastToItkImage(image, itkImage); + + typedef itk::Image FloatImageType; + typedef itk::NormalizeImageFilter< itk::Image, FloatImageType > + NormalizeFilterType; + NormalizeFilterType::Pointer normalizeFilter = NormalizeFilterType::New(); + normalizeFilter->SetInput(itkImage); + normalizeFilter->Update(); + + mitk::Image::Pointer normalizedImage; + mitk::CastToMitkImage(normalizeFilter->GetOutput(), normalizedImage); + + return normalizedImage; + } + return nullptr; +} +void NormalizeAll(mitk::DataStorage::Pointer datastorage) +{ + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull() + && !QString(dataNode->GetName().c_str()).contains( QString("Tibia"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains( QString("Fibula"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains( QString("Talus"), Qt::CaseInsensitive)) + { + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + // Cast to MITK + dataNode->SetData(Normalize(image)); + // Reinit node + mitk::RenderingManager::GetInstance()->InitializeViews( + dataNode->GetData()->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + + } + } +} +///***************************************END NORMALIZE *********************************************************************/ +///********************************************************************************************************************** / + + + +///***************************************CUT****************************************************************************/ +bool QmitkShapeModelUtil::GetAxisPositions(mitk::DataNode::Pointer node) +{ + //get the planePositionManager Service + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_shapemodelutil_Activator::GetContext(); + ctkServiceReference ppmRef = context->getServiceReference(); + mitk::PlanePositionManagerService* service = context->getService(ppmRef); + service->RemoveAllPlanePositions(); + + 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 + markers = this->GetDataStorage()->GetDerivations(node, isMarker); + (node)->SetVisibility(true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage()); + + 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); + } + + // mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + (*iter)->GetIntProperty("Plane Position ID", markerId); + this->LoadPositionNode((*iter), markerId); + } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + for (int i = 1; i <= 3; i++) + { + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << i; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + } + return true; + } + return false; +} + + + + +void QmitkShapeModelUtil::CutAllAnkles(mitk::DataStorage::Pointer datastorage, int axis, double offset) +{ + MITK_INFO << "Cut all images"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull() + && !QString(dataNode->GetName().c_str()).contains(QString("Tibia"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains(QString("Fibula"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains(QString("Talus"), Qt::CaseInsensitive)) + { + GetAxisPositions(dataNode); + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + MITK_INFO << dataNode->GetName(); + // get axial render window and corresponding plane + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << 1; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + + if (!rendereri) + return; + + const mitk::PlaneGeometry* plane = dynamic_cast(rendereri->GetCurrentWorldPlaneGeometry()); + mitk::PlaneGeometry::Pointer newAxiPlane = mitk::PlaneGeometry::New(); + //mitk::PlaneGeometry* newAxiPlane = mitk::PlaneGeometry::New(); + newAxiPlane = plane->Clone(); + mitk::Vector3D normal = newAxiPlane->GetNormal(); + newAxiPlane->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); // normal already in world cords?! + newAxiPlane->Translate(normal * offset); + + try + { + mitk::DataNode* fibulaNode(this->GetDataStorage()->GetNamedNode(dataNode->GetName() + "_Fibula")); + mitk::Image::Pointer imagefibula = dynamic_cast(fibulaNode->GetData()); + auto cutterFibula = mitk::UpperAnkleCropper::New(); + cutterFibula->SetPlane(newAxiPlane); + cutterFibula->SetUsePositiveDirection(false); + cutterFibula->SetInput(imagefibula); + + mitk::DataNode* tibiaNode(this->GetDataStorage()->GetNamedNode(dataNode->GetName() + "_Tibia")); + mitk::Image::Pointer imagetibia = dynamic_cast(tibiaNode->GetData()); + auto cutterTibia = mitk::UpperAnkleCropper::New(); + cutterTibia->SetPlane(newAxiPlane); + cutterTibia->SetOutsideValue(0); + cutterTibia->SetUsePositiveDirection(false); + cutterTibia->SetInput(imagetibia); + + // do the actual cutting + try + { + cutterTibia->Update(); + cutterFibula->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + // mitk::IOUtil::SaveImage(cutter->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Tibia.nrrd"); + tibiaNode->SetData(cutterTibia->GetOutput()->Clone()); + fibulaNode->SetData(cutterFibula->GetOutput()->Clone()); + + // Reinit node + mitk::RenderingManager::GetInstance()->InitializeViews( + tibiaNode->GetData()->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + "_Tibia" + " does not exist"; + } + + } + + } + } +} + +void QmitkShapeModelUtil::CutAnkle(mitk::DataStorage::Pointer datastorage, int axis, double offset) +{ + MITK_INFO << "Cut image"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + GetAxisPositions(dataNode); + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + // get axial render window and corresponding plane + std::stringstream multiWidgetStream; + multiWidgetStream << "stdmulti.widget"; + multiWidgetStream << 1; + std::string multiWidgetString = multiWidgetStream.str(); + mitk::BaseRenderer *rendereri = mitk::BaseRenderer::GetByName(multiWidgetString.c_str()); + + if (!rendereri) + return; + + const mitk::PlaneGeometry* plane = dynamic_cast(rendereri->GetCurrentWorldPlaneGeometry()); + mitk::PlaneGeometry::Pointer newAxiPlane = mitk::PlaneGeometry::New(); + //mitk::PlaneGeometry* newAxiPlane = mitk::PlaneGeometry::New(); + newAxiPlane = plane->Clone(); + mitk::Vector3D normal = newAxiPlane->GetNormal(); + newAxiPlane->GetIndexToWorldTransform()->GetInverseTransform()->TransformVector(normal); // normal already in world cords?! + newAxiPlane->Translate(normal * -offset); + + try + { + mitk::Image::Pointer tibia = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Tibia.nrrd"); + auto croppedImageNode = mitk::DataNode::New(); + auto cutter = mitk::UpperAnkleCropper::New(); + cutter->SetPlane(newAxiPlane); + + // adjustable in advanced settings + cutter->SetUsePositiveDirection(false); + cutter->SetInput(tibia); + // do the actual cutting + try + { + cutter->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + mitk::IOUtil::SaveImage(cutter->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Tibia.nrrd"); + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Tibia.nrrd" + " does not exist"; + } + + + + try + { + mitk::Image::Pointer fibula = mitk::IOUtil::LoadImageA("C:/Users/thomass.AD/Desktop/Input/" + dataNode->GetName() + " Fibula.nrrd"); + + auto cutter2 = mitk::UpperAnkleCropper::New(); + cutter2->SetPlane(newAxiPlane); + + + cutter2->SetUsePositiveDirection(false); + cutter2->SetInput(fibula); + // do the actual cutting + try + { + cutter2->Update(); + } + catch (const itk::ExceptionObject& e) + { + std::string message = std::string("The Cropping filter could not process because of: \n ") + e.GetDescription(); + + QMessageBox::warning(nullptr, + tr("Cropping not possible!"), + tr(message.c_str()), + QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); + return; + } + + mitk::IOUtil::SaveImage(cutter2->GetOutput(), "C:/Users/thomass.AD/Desktop/Output/" + dataNode->GetName() + " Fibula.nrrd"); + + } + catch (const itk::ExceptionObject& e) + { + MITK_INFO << dataNode->GetName() + " Fibula.nrrd" + " does not exist"; + } + } + } + + } +} + + +//*************************************** END CUT *********************************************************************/ +//**********************************************************************************************************************/ + + +//***************************************MIRROR****************************************************************************/ + +void FlipImage(int axis, mitk::DataNode::Pointer dataNode) +{ + + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + + if (image != nullptr) + { + if (image.IsNull()) + return; + + auto flipMatrix = vtkSmartPointer::New(); + flipMatrix->Identity(); + switch (axis) + { + case 0: + flipMatrix->SetElement(0, 0, -1); + break; + case 1: + flipMatrix->SetElement(1, 1, -1); + break; + case 2: + flipMatrix->SetElement(2, 2, -1); + break; + } + + auto flipTransform = vtkSmartPointer::New(); + flipTransform->SetMatrix(flipMatrix); + flipTransform->Concatenate(image->GetGeometry()->GetVtkMatrix()); + flipTransform->Update(); + image->GetGeometry()->SetIndexToWorldTransformByVtkMatrixWithoutChangingSpacing(flipTransform->GetMatrix()); + + // ITK Flip + // // Flip image + // FlipImageFilterType::Pointer flipper = FlipImageFilterType::New(); + // flipper->SetInput(image); + // int param1 = 0; + // itk::FixedArray flipAxes; + // for (int i = 0; i<3; ++i) + // { + // if (i == param1) + // { + // flipAxes[i] = true; + // } + // else + // { + // flipAxes[i] = false; + // } + // } + // flipper->SetFlipAxes(flipAxes); + // flipper->UpdateLargestPossibleRegion(); + // mitkImage = mitk::ImportItkImage(flipper->GetOutput())->Clone(); + // std::cout << "Image flipping successful." << std::endl; + // + } + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + mitk::IOUtil::SaveImage(image, "C:/Users/thomass.AD/Desktop/Test/" + dataNode->GetName() + ".nrrd"); + +} + +#include +typedef itk::Image ImageType; // TODO: change to support other datatypes +typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; + +void FlipAll(mitk::DataStorage::Pointer datastorage) +{ + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + + FlipImage(0, dataNode); + + } + } + } +} +/*************************************** END MIRROR *********************************************************************/ +/************************************************************************************************************************/ +double* CenterOfMass(vtkSmartPointer polyData) +{ + auto centerOfMassFilter = vtkSmartPointer::New(); + centerOfMassFilter->SetInputData(polyData); + centerOfMassFilter->SetUseScalarsAsWeights(false); + centerOfMassFilter->Update(); + double center[3]; + centerOfMassFilter->GetCenter(center); + std::cout << "Center of mass is " << center[0] << " " << center[1] << " " << center[2] << std::endl; + return center; +} + +/*************************************** REGISTER ****************************************************************************/ +void ConvertToSurface(mitk::Image::Pointer segmentation, mitk::Surface::Pointer& surface) +{ + // Create a contour from the binary image + auto surfaceFilter = mitk::ManualSegmentationToSurfaceFilter::New(); + surfaceFilter->SetInput(segmentation); + surfaceFilter->SetThreshold(1); //expects binary image with zeros and ones + surfaceFilter->SetGaussianStandardDeviation(1.0); + surfaceFilter->SetMedianFilter3D(true); // apply median to segmentation before marching cubes ? + surfaceFilter->SetDecimate(mitk::ImageToSurfaceFilter::NoDecimation); + surfaceFilter->UpdateLargestPossibleRegion(); + surface = surfaceFilter->GetOutput()->Clone(); +} + +void QmitkShapeModelUtil::RegisterAll(mitk::DataStorage::Pointer datastorage, mitk::DataNode::Pointer node) +{ + MITK_INFO << "Register all images"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + auto targetPoints = vtkSmartPointer::New(); + auto movingPoints = vtkSmartPointer::New(); + + if (node.IsNotNull()) + { + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + mitk::Image::Pointer tibiaTarget = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + node->GetName() + " Tibia.nrrd"); + mitk::Image::Pointer fibulaTarget = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + node->GetName() + " Fibula.nrrd"); + mitk::Image::Pointer talusTarget = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + node->GetName() + " Talus.nrrd"); + + auto tibiaTargetSurface = mitk::Surface::New(); + auto fibulaTargetSurface = mitk::Surface::New(); + auto talusTargetSurface = mitk::Surface::New(); + + ConvertToSurface(tibiaTarget, tibiaTargetSurface); + ConvertToSurface(fibulaTarget, fibulaTargetSurface); + ConvertToSurface(talusTarget, talusTargetSurface); + + double* centerTibiaTarget = CenterOfMass(tibiaTargetSurface->GetVtkPolyData()); + double* centerFibulaTarget = CenterOfMass(fibulaTargetSurface->GetVtkPolyData()); + double* centerTalusTarget = CenterOfMass(talusTargetSurface->GetVtkPolyData()); + + targetPoints->InsertNextPoint(centerTibiaTarget); + targetPoints->InsertNextPoint(centerFibulaTarget); + targetPoints->InsertNextPoint(centerTalusTarget); + //auto centerOfMassFilter = vtkSmartPointer::New(); + //centerOfMassFilter->SetInputData(tibiaTarget->GetVtkPolyData()); + //centerOfMassFilter->SetUseScalarsAsWeights(false); + //centerOfMassFilter->Update(); + //double centerFibulaTarget[3]; + //centerOfMassFilter->GetCenter(centerFibulaTarget); + //std::cout << "Center of mass is " << centerFibulaTarget[0] << " " << centerFibulaTarget[1] << " " << centerFibulaTarget[2] << std::endl; + + + if (!images->empty()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull() + && !QString(dataNode->GetName().c_str()).contains(QString("Tibia"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains(QString("Fibula"), Qt::CaseInsensitive) + && !QString(dataNode->GetName().c_str()).contains(QString("Talus"), Qt::CaseInsensitive)) + { + mitk::Image::Pointer imageMoving = dynamic_cast(dataNode->GetData()); + mitk::Image::Pointer tibiaMoving = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + dataNode->GetName() + " Tibia.nrrd"); + mitk::Image::Pointer fibulaMoving = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + dataNode->GetName() + " Fibula.nrrd"); + mitk::Image::Pointer talusMoving = mitk::IOUtil::LoadImageA(m_WorkingDirectory.toStdString() + dataNode->GetName() + " Talus.nrrd"); + + auto tibiaMovingSurface = mitk::Surface::New(); + auto fibulaMovingSurface = mitk::Surface::New(); + auto talusMovingSurface = mitk::Surface::New(); + + ConvertToSurface(tibiaMoving, tibiaMovingSurface); + ConvertToSurface(fibulaMoving, fibulaMovingSurface); + ConvertToSurface(talusMoving, talusMovingSurface); + + double* centerTibiaMoving = CenterOfMass(tibiaMovingSurface->GetVtkPolyData()); + double* centerFibulaMoving = CenterOfMass(fibulaMovingSurface->GetVtkPolyData()); + double* centerTalusMoving = CenterOfMass(talusMovingSurface->GetVtkPolyData()); + movingPoints->InsertNextPoint(centerTibiaMoving); + movingPoints->InsertNextPoint(centerFibulaMoving); + movingPoints->InsertNextPoint(centerTalusMoving); + + // Landmark Registration + auto landmarkTransform = vtkSmartPointer::New(); + landmarkTransform->SetSourceLandmarks(movingPoints); + landmarkTransform->SetTargetLandmarks(targetPoints); + landmarkTransform->SetModeToRigidBody(); + landmarkTransform->Update(); + } + } + + } + } +} + +/*************************************** END REGISTER *********************************************************************/ +/************************************************************************************************************************* / + + + /*************************************** SCRIPT ****************************************************************************/ +void QmitkShapeModelUtil::ScriptAll(mitk::DataStorage::Pointer datastorage) +{ + MITK_INFO << "Create Scripts for all images"; + MITK_INFO << "Register all images"; + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::DataStorage::SetOfObjects::ConstPointer images = datastorage->GetSubset(isImage); + + ofstream fileOrgis(m_WorkingDirectory.toStdString() + "origs.txt"); + ofstream fileCreateSurfaceTibia(m_WorkingDirectory.toStdString() + "CreateSurfaceTibia.bat"); + ofstream fileConvertMeshTibia(m_WorkingDirectory.toStdString() + "ConvertMeshTibia.bat"); + + ofstream fileCreateSurfaceFibula(m_WorkingDirectory.toStdString() + "CreateSurfaceFibula.bat"); + ofstream fileConvertMeshFibula(m_WorkingDirectory.toStdString() + "ConvertMeshFibula.bat"); + + ofstream fileCreateSurfaceTalus(m_WorkingDirectory.toStdString() + "CreateSurfaceTalus.bat"); + ofstream fileConvertMeshTalus(m_WorkingDirectory.toStdString() + "ConvertMeshTalus.bat"); + + + + int it = 0; + if (!images->empty()) + { + + + if (fileOrgis.is_open() + && fileCreateSurfaceTibia.is_open() && fileConvertMeshTibia.is_open() + && fileCreateSurfaceFibula.is_open() && fileConvertMeshFibula.is_open() + && fileCreateSurfaceTalus.is_open() && fileConvertMeshTalus.is_open()) + { + //iterate over all child nodes with NodePredicateProperty + for (mitk::DataStorage::SetOfObjects::const_iterator iter = images->begin(); iter != images->end(); ++iter) + { + mitk::DataNode::Pointer dataNode = (*iter); + if (dataNode.IsNotNull()) + { + mitk::Image::Pointer image = dynamic_cast(dataNode->GetData()); + // origs.txt + fileOrgis << m_WorkingDirectory.toStdString() + dataNode->GetName()+"\n"; + // CreateSurface.bat + fileCreateSurfaceTibia << "CreateSurfaceModel " + m_WorkingDirectory.toStdString() + "Tibia\Segm\\" + dataNode->GetName() + " " + m_WorkingDirectory.toStdString() + "Tibia\Surface\image" + std::to_string(it) + " - q 0.0\n"; + fileCreateSurfaceFibula << "CreateSurfaceModel " + m_WorkingDirectory.toStdString() + "Fibula\Segm\\" + dataNode->GetName() + " " + m_WorkingDirectory.toStdString() + "Fibula\Surface\image" + std::to_string(it) + " - q 0.0\n"; + fileCreateSurfaceTalus << "CreateSurfaceModel " + m_WorkingDirectory.toStdString() + "Talus\Segm\\" + dataNode->GetName() + " " + m_WorkingDirectory.toStdString() + "Talus\Surface\image" + std::to_string(it) + " - q 0.0\n"; + + // ConvertMesh.bat + fileConvertMeshTibia << "ConvertMesh " + m_WorkingDirectory.toStdString() + "Tibia\Surface\image" + std::to_string(it) + ".stl " + m_WorkingDirectory.toStdString() + "Tibia\Meshes\image" + std::to_string(it) + " 2\n"; + fileConvertMeshFibula << "ConvertMesh " + m_WorkingDirectory.toStdString() + "Fibula\Surface\image" + std::to_string(it) + ".stl " + m_WorkingDirectory.toStdString() + "Fibula\Meshes\image" + std::to_string(it) + " 2\n"; + fileConvertMeshTalus << "ConvertMesh " + m_WorkingDirectory.toStdString() + "Talus\Surface\image" + std::to_string(it) + ".stl " + m_WorkingDirectory.toStdString() + "Talus\Meshes\image" + std::to_string(it) + " 2\n"; + } + } + fileOrgis.close(); + fileCreateSurfaceTibia.close(); + fileConvertMeshTibia.close(); + fileCreateSurfaceFibula.close(); + fileConvertMeshFibula.close(); + fileCreateSurfaceTalus.close(); + fileConvertMeshTalus.close(); + } + } +} +// origs.txt + +// Surface +// CreateSurface.bat +// CreateSurfaceModel X:\PathTo\Segm\image01.pic.gz X:\PathTo\Surface\image01 - q 0.0 + +// ConvertMesh X:\PathTo\Surfaces\image01.stl X:\PathTo\Meshes\image01 2 + + /*************************************** END SCRIPT *********************************************************************/ + /*************************************************************************************/ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.h b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.h new file mode 100644 index 0000000000..aaffe7c7ae --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkShapeModelUtil.h @@ -0,0 +1,156 @@ +/*========================================================================= + +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 QmitkShapeModelUtil_h +#define QmitkShapeModelUtil_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_QmitkShapeModelUtilControls.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 QmitkShapeModelUtil : 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: + + QmitkShapeModelUtil(QObject *parent = 0); + + virtual ~QmitkShapeModelUtil(); + + 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 ToggleShapeModelUtilView(); + + /// \brief Calculate and save intersection lines between the planes to file + void SaveIntersectionFromNodeToFile(); + + void LoadPositionFromFile(); + + + /// \brief + void OnMirrorClicked(); + void OnMirrorAllClicked(); + void OnNormalizeClicked(); + void OnNormalizeAllClicked(); + void OnCutClicked(); + void OnCutAllClicked(); + void OnRegistrationClicked(); + void OnScriptAllClicked(); + void OnChangeFolderClicked(); + + /// + void CutAllAnkles(mitk::DataStorage::Pointer dataStorage, int axis, double offset); + void CutAnkle(mitk::DataStorage::Pointer datastorage, int axis, double offset); + bool GetAxisPositions(mitk::DataNode::Pointer node); + void RegisterAll(mitk::DataStorage::Pointer datastorage, mitk::DataNode::Pointer node); + void ScriptAll(mitk::DataStorage::Pointer datastorage); + /// + + +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(); + + QString m_WorkingDirectory; + + + Ui::QmitkShapeModelUtilControls m_Controls; + + +}; + + +#endif // QmitkShapeModelUtil_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneTool.cpp b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneTool.cpp new file mode 100644 index 0000000000..6abdea45e0 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneTool.cpp @@ -0,0 +1,659 @@ + +/*=================================================================== + +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 +#include "mitkNodePredicateProperty.h" +#include "mitkNodePredicateDataType.h" +#include +#include +#include +#include "mitkPlanePositionManager.h" +#include "mitkPlanarCircle.h" +#include +#include "mitkVtkRepresentationProperty.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 + + +//QmitkStandardPlaneTool(parent) +QmitkStandardPlaneTool::QmitkStandardPlaneTool(QObject *parent = 0) : +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(ToggleShapeModelUtilView())); + connect(m_Controls.pB_savePosition, SIGNAL(clicked()), this, SLOT(AddPositionNode())); + connect(m_Controls.pB_loadPositions, SIGNAL(clicked()), this, SLOT(LoadPositionFromNode())); + connect(m_Controls.pB_LoadFromFile, SIGNAL(clicked()), this, SLOT(LoadPositionFromFile())); + m_Controls.gB_StandardPlaneTool->hide(); + m_Controls.patientImageSelector->setEnabled(true); +} + +void QmitkStandardPlaneTool::ToggleShapeModelUtilView() +{ + 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_shapemodelutil_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_shapemodelutil_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_shapemodelutil_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_shapemodelutil_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::LoadPositionFromFile() +{ + + QString fileName = QFileDialog::getOpenFileName(NULL, + tr("Open Scene File with Positions"),0, tr("MITK scene file (*.mitk)")); + + MITK_INFO << fileName; + + mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New(); + mitk::DataStorage::Pointer dataStorage = sceneIO->LoadScene(fileName.toStdString(), 0, true); + + + MITK_INFO << m_Controls.patientImageSelector->currentIndex(); + if (m_Controls.patientImageSelector->currentIndex() <0) + return; + + //get the planePositionManager Service + ctkPluginContext* context = mitk::org_mitk_gui_qt_shapemodelutil_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 = dataStorage->GetSubset(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); + this->GetDataStorage()->Add(coronalPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(axialPosNode, imageNode); + } + 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); + this->GetDataStorage()->Add(sagittalPosNode, imageNode); + } + + (*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.shapemodelutil/src/internal/QmitkStandardPlaneTool.h b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneTool.h new file mode 100644 index 0000000000..52df4c3b14 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneTool.h @@ -0,0 +1,133 @@ +/*========================================================================= + +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 QmitkShapeModelUtil_h +#define QmitkShapeModelUtil_h + +#include + +#ifdef WIN32 +#pragma warning( disable : 4250 ) +#endif + +#include +#include "QVTKWidget.h" +#include +#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_QmitkStandardPlaneToolWidgetControls.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 QWidget +{ + // 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) + + Q_OBJECT + +public: + + explicit QmitkStandardPlaneTool(QWidget *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 ToggleShapeModelUtilView(); + + /// \brief Calculate and save intersection lines between the planes to file + void SaveIntersectionFromNodeToFile(); + + void LoadPositionFromFile(); + +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::QmitkStandardPlaneToolWidgetControls m_Controls; + + +}; + + +#endif // QmitkShapeModelUtil_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneToolWidgetControls.ui b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneToolWidgetControls.ui new file mode 100644 index 0000000000..fe3290a32e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/QmitkStandardPlaneToolWidgetControls.ui @@ -0,0 +1,158 @@ + + + QmitkStandardPlaneToolWidgetControls + + + + 0 + 0 + 290 + 790 + + + + + 0 + 0 + + + + + 290 + 790 + + + + + 16777215 + 16777215 + + + + QmitkTemplate + + + + + 10 + 180 + 251 + 161 + + + + + 0 + 0 + + + + Standard Plane Tool + + + + + + + + Set New Position + + + + + + + Load Current Position + + + + + + + Load Positions From File + + + + + + + false + + + Save All Positionsnodes To File + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 20 + 150 + 231 + 22 + + + + + + + false + + + + 0 + 0 + + + + + + + + false + + + + 0 + 0 + + + + Images + + + Qt::AlignCenter + + + + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.cpp b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.cpp new file mode 100644 index 0000000000..1acbc2ded9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.cpp @@ -0,0 +1,311 @@ +/*=================================================================== + +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 "mitkUpperAnkleCropper.h" +#include "mitkGeometry3D.h" +#include "mitkImageAccessByItk.h" +#include "mitkImageToItk.h" +#include "mitkImageCast.h" +#include "mitkStatusBar.h" +#include "mitkTimeHelper.h" + +#include + +#include "vtkMatrix4x4.h" +#include "vtkSmartPointer.h" +#include "vtkTransform.h" + +#include "itkImageRegionIteratorWithIndex.h" +#include +#include +#include +#include + + +namespace mitk +{ + UpperAnkleCropper::UpperAnkleCropper() + : m_Plane(nullptr), + m_OutsideValue(0), + m_UsePositiveDirection(false), + m_InputTimeSelector(mitk::ImageTimeSelector::New()), + m_OutputTimeSelector(mitk::ImageTimeSelector::New()) + { + this->SetNumberOfIndexedInputs(1); + this->SetNumberOfRequiredInputs(1); + } + + UpperAnkleCropper::~UpperAnkleCropper() + { + } + + + template < typename TPixel, unsigned int VImageDimension > + void UpperAnkleCropper::CutImage(itk::Image< TPixel, VImageDimension >* inputItkImage, int timeStep) + { + MITK_INFO << "Scalar Pixeltype" << std::endl; + + typedef TPixel TOutputPixel; + typedef itk::Image ItkInputImageType; + typedef itk::Image ItkOutputImageType; + typedef typename itk::ImageBase::RegionType ItkRegionType; + typedef itk::ImageRegionIteratorWithIndex< ItkInputImageType > ItkInputImageIteratorType; + typedef itk::ImageRegionIteratorWithIndex< ItkOutputImageType > ItkOutputImageIteratorType; + + TOutputPixel outsideValue = this->m_OutsideValue; + // currently 0 if not set in advance + // TODO: change default value to itk::NumericTraits::min(); + + if (this->m_Plane.IsNull()) + return; + + if (inputItkImage == nullptr) + { + mitk::StatusBar::GetInstance()->DisplayErrorText("An internal error occurred. Can't convert Image. Please report to bugs@mitk.org"); + std::cout << " image is NULL...returning" << std::endl; + return; + } + + // first convert the index + typename ItkRegionType::IndexType::IndexValueType tmpIndex[3]; + itk2vtk(this->m_InputRequestedRegion.GetIndex(), tmpIndex); + typename ItkRegionType::IndexType index; + index.SetIndex(tmpIndex); + + // then convert the size + typename ItkRegionType::SizeType::SizeValueType tmpSize[3]; + itk2vtk(this->m_InputRequestedRegion.GetSize(), tmpSize); + typename ItkRegionType::SizeType size; + size.SetSize(tmpSize); + + //create the ITK-image-region out of index and size + ItkRegionType inputRegionOfInterest(index, size); + + + // Get access to the MITK output image via an ITK image + typename mitk::ImageToItk::Pointer outputimagetoitk = mitk::ImageToItk::New(); + outputimagetoitk->SetInput(this->m_OutputTimeSelector->GetOutput()); + outputimagetoitk->Update(); + typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput(); + + // create the iterators + ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest); + ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion()); + + // Cut the boundingbox out of the image by iterating through all images + // TODO: use more efficient method by using the contour instead off all single pixels + mitk::Point3D p; + mitk::BaseGeometry* inputGeometry = this->GetInput()->GetGeometry(timeStep); + double distanceToPlane; + for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt) + { + vtk2itk(inputIt.GetIndex(), p); + if ((TOutputPixel)inputIt.Value() != outsideValue) + { + inputGeometry->IndexToWorld(p, p); + distanceToPlane = m_Plane->SignedDistanceFromPlane(p); + + //if (distanceToPlane>0) + // MITK_INFO << distanceToPlane; + distanceToPlane > 0 ? outputIt.Set((TOutputPixel)inputIt.Value()) : outputIt.Set(outsideValue); + } + else + outputIt.Set((TOutputPixel)inputIt.Value()); + } + } + + + void UpperAnkleCropper::SetPlane(const mitk::PlaneGeometry * plane) + { + m_Plane = const_cast(plane); + // Process object is not const-correct so the const_cast is required here + // this->ProcessObject::SetNthInput(1, plane); + } + + const mitk::PixelType UpperAnkleCropper::GetOutputPixelType() + { + return this->GetInput()->GetPixelType(); + } + + void UpperAnkleCropper::GenerateInputRequestedRegion() + { + mitk::Image* output = this->GetOutput(); + if ((output->IsInitialized() == false) || (m_Plane.IsNull())) + return; + + GenerateTimeInInputRegion(output, const_cast (this->GetInput())); + } + + void UpperAnkleCropper::GenerateOutputInformation() + { + + // Set Cropping region + mitk::Image::Pointer output = this->GetOutput(); + if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime())) + return; + + mitk::Image::Pointer input = const_cast (this->GetInput()); + + if (input.IsNull()) + { + mitkThrow() << "Input is not a mitk::Image"; + } + itkDebugMacro(<< "GenerateOutputInformation()"); + + unsigned int dimension = input->GetDimension(); + if (dimension < 3) + { + mitkThrow() << "Cropper cannot handle 1D or 2D Objects."; + } + + + mitk::BaseGeometry* inputImageGeometry = input->GetSlicedGeometry(); + + // pre-initialize input-requested-region to largest-possible-region + m_InputRequestedRegion = input->GetLargestPossibleRegion(); + + + //initialize output image + auto dimensions = new unsigned int[dimension]; + if (dimension > 3) + memcpy(dimensions + 3, input->GetDimensions() + 3, (dimension - 3)*sizeof(unsigned int)); + else + dimension = 3; // set timeStep to zero if GetUseCropTimeStepOnly is true + + itk2vtk(m_InputRequestedRegion.GetSize(), dimensions); + + output->Initialize(mitk::PixelType(GetOutputPixelType()), dimension, dimensions); + delete[] dimensions; + + // Apply transform of the input image to the new generated output image + mitk::UpperAnkleCropper::RegionType outputRegion = output->GetRequestedRegion(); + const mitk::TimeGeometry *inputTimeGeometry = input->GetTimeGeometry(); + + m_TimeOfHeaderInitialization.Modified(); + } + + void UpperAnkleCropper::ComputeData(mitk::Image* image, int boTimeStep) + { + // examine dimension and pixeltype + if ((image == nullptr) || (image->GetDimension() > 4) || (image->GetDimension() <= 2)) + { + MITK_ERROR << "Filter cannot handle dimensions less than 2 and greater than 4" << std::endl; + itkExceptionMacro("Filter cannot handle dimensions less than 2 and greater than 4"); + return; + } + + // Check if pixeltype is rgb + const mitk::PixelType &pixelType = image->GetPixelType(); + + if ((pixelType.GetPixelType() == itk::ImageIOBase::RGB) || (pixelType.GetPixelType() == itk::ImageIOBase::RGBA)) + { + MITK_INFO << "is rgb"; + switch (pixelType.GetComponentType()) + { + case itk::ImageIOBase::UCHAR: + { + AccessFixedPixelTypeByItk_1(image, CutImage, (itk::RGBPixel), boTimeStep); + } + case itk::ImageIOBase::USHORT: + { + AccessFixedPixelTypeByItk_1(image, CutImage, (itk::RGBPixel), boTimeStep); + break; + } + case itk::ImageIOBase::FLOAT: + { + AccessFixedPixelTypeByItk_1(image, CutImage, (itk::RGBPixel), boTimeStep); + break; + } + case itk::ImageIOBase::DOUBLE: + { + AccessFixedPixelTypeByItk_1(image, CutImage, (itk::RGBPixel), boTimeStep); + break; + } + default: + MITK_ERROR << "Can not handle pixel component type " << pixelType.GetComponentType(); + return; + } + } + else if (pixelType.GetPixelType() == itk::ImageIOBase::SCALAR) + { + switch (image->GetDimension()) + { + case 2: + { + AccessFixedDimensionByItk_1(image, CutImage, 2, boTimeStep); break; + } + case 3: + { + AccessFixedDimensionByItk_1(image, CutImage, 3, boTimeStep); break; + } + case 4: + { + AccessFixedDimensionByItk_1(image, CutImage, 4, boTimeStep); break; + } + default: break; + } + } + else + { + MITK_ERROR << "Unsupported pixel type" << std::endl; + } + } + + void UpperAnkleCropper::GenerateData() + { + MITK_INFO << "Generate Data" << std::endl; + mitk::Image::ConstPointer input = this->GetInput(); + mitk::Image::Pointer output = this->GetOutput(); + + if (input.IsNull()) + return; + + if ((output->IsInitialized() == false) || (m_Plane.IsNull())) + return; + + m_InputTimeSelector->SetInput(input); + m_OutputTimeSelector->SetInput(this->GetOutput()); + + mitk::UpperAnkleCropper::RegionType outputRegion = output->GetRequestedRegion(); + mitk::BaseGeometry* inputImageGeometry = input->GetSlicedGeometry(); + + // iterate over all time steps and perform cropping or masking on all or a specific timestep (perviously specified by UseCurrentTimeStepOnly) + int tstart = outputRegion.GetIndex(3); + int tmax = tstart + outputRegion.GetSize(3); + int t; + for (t = tstart; t < tmax; ++t) + { + mitk::SlicedGeometry3D* slicedGeometry = output->GetSlicedGeometry(t); + auto indexToWorldTransform = AffineTransform3D::New(); + indexToWorldTransform->SetParameters(input->GetSlicedGeometry(t)->GetIndexToWorldTransform()->GetParameters()); + slicedGeometry->SetIndexToWorldTransform(indexToWorldTransform); + + const mitk::SlicedData::IndexType& start = m_InputRequestedRegion.GetIndex(); + mitk::Point3D origin; vtk2itk(start, origin); + inputImageGeometry->IndexToWorld(origin, origin); + slicedGeometry->SetOrigin(origin); + m_InputTimeSelector->SetTimeNr(t); + m_InputTimeSelector->UpdateLargestPossibleRegion(); + m_OutputTimeSelector->SetTimeNr(t); + m_OutputTimeSelector->UpdateLargestPossibleRegion(); + ComputeData(m_InputTimeSelector->GetOutput(), t); + } + m_InputTimeSelector->SetInput(nullptr); + m_OutputTimeSelector->SetInput(nullptr); + m_TimeOfHeaderInitialization.Modified(); + } + +} // of namespace mitk \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.h b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.h new file mode 100644 index 0000000000..24b36d9c6a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/mitkUpperAnkleCropper.h @@ -0,0 +1,130 @@ +/*=================================================================== + +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 UPPERANKLECROPPER_H +#define UPPERANKLECROPPER_H + +#include "mitkCommon.h" +#include "mitkGeometryData.h" +#include "mitkImageToImageFilter.h" +#include "mitkImageTimeSelector.h" +#include "mitkImageAccessByItk.h" +#include "itkImage.h" + +namespace mitk { + + /** Documentation + * @brief Masks a segmentation defined by normal out of an mitk Image + * + * Input Parameters are a mitk::PlaneGeometry and an mitk::Image + * Masking: Pixel below normal will have a pixelvalue of m_OutsideValue + */ + //## @ingroup Process + class UpperAnkleCropper : public ImageToImageFilter + { + public: + mitkClassMacro(UpperAnkleCropper, ImageToImageFilter); + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** + * @brief Set geometry of the bounding object + */ + void SetPlane(const mitk::PlaneGeometry * plane); + + /** + * @brief Sets and Gets whether a masking or cropping needs to be performed + */ + itkSetMacro(UsePositiveDirection, bool); + itkGetMacro(UsePositiveDirection, bool); + + /** + * @brief Sets and Gets the outside value for masking + */ + itkSetMacro(OutsideValue, ScalarType); + itkGetMacro(OutsideValue, ScalarType); + + /** + * @brief Sets and Gets the outside value for masking + */ + itkSetMacro(InsideValue, ScalarType); + itkGetMacro(InsideValue, ScalarType); + + protected: + UpperAnkleCropper(); + virtual ~UpperAnkleCropper(); + + virtual const PixelType GetOutputPixelType(); + + /** + * @brief Reimplemented from ImageToImageFilter + */ + virtual void GenerateInputRequestedRegion() override; + virtual void GenerateOutputInformation() override; + virtual void GenerateData() override; + + /** + * @brief Template Function for cropping and masking images with scalar pixel type + */ + template < typename TPixel, unsigned int VImageDimension > + void CutImage(itk::Image< TPixel, VImageDimension >* inputItkImage, int timeStep); + /** + *@brief Process the image and create the output + **/ + virtual void ComputeData(mitk::Image* input3D, int boTimeStep); + + // virtual void ComputeData(mitk::LabelSetImage* image, int boTimeStep); + + private: + /** + *@brief PlaneGeometry encapsulates the cut plane + **/ + mitk::PlaneGeometry ::Pointer m_Plane; + + /** + * @brief scalar value for outside pixels (default: 0) + */ + ScalarType m_OutsideValue; + + /** + * @brief scalar value for inside pixels (default: 1) + */ + ScalarType m_InsideValue; + + + bool m_UsePositiveDirection; + /** + * @brief Select single input image in a timeseries + */ + mitk::ImageTimeSelector::Pointer m_InputTimeSelector; + /** + * @brief Select single output image in a timeseries + */ + mitk::ImageTimeSelector::Pointer m_OutputTimeSelector; + /** + * @brief Region of input needed for cutting + */ + typedef itk::ImageRegion<5> RegionType; + + mitk::SlicedData::RegionType m_InputRequestedRegion; + /** + * @brief Time when Header was last initialized + **/ + itk::TimeStamp m_TimeOfHeaderInitialization; + + }; +} // namespace mitk +#endif /* UPPERANKLECROPPER_H */ \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_Activator.cpp b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_Activator.cpp new file mode 100644 index 0000000000..8ac290b8f5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_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_shapemodelutil_Activator.h" + +#include + +#include "QmitkShapeModelUtil.h" +#include +#include + +US_INITIALIZE_MODULE + +namespace mitk { + ctkPluginContext* org_mitk_gui_qt_shapemodelutil_Activator::m_Context = 0; + + void org_mitk_gui_qt_shapemodelutil_Activator::start(ctkPluginContext* context) + { +// RegisterBoundingShapeObjectFactory(); + BERRY_REGISTER_EXTENSION_CLASS(QmitkShapeModelUtil, context) + m_Context = context; + } + + void org_mitk_gui_qt_shapemodelutil_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context) + } + + ctkPluginContext* org_mitk_gui_qt_shapemodelutil_Activator::GetContext() + { + return m_Context; + } +} + +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +Q_EXPORT_PLUGIN2(org_mitk_gui_qt_shapemodelutil, mitk::PluginActivator) +#endif \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_Activator.h b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_Activator.h new file mode 100644 index 0000000000..f7e2c5aa80 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.shapemodelutil/src/internal/org_mitk_gui_qt_shapemodelutil_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_shapemodelutil_Activator_h +#define org_mitk_gui_qt_shapemodelutil_Activator_h + +#include + +namespace mitk { + + class org_mitk_gui_qt_shapemodelutil_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_shapemodelutil") +#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_shapemodelutil_Activator_h