diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index 5577f880ae..30773d01f6 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,321 +1,322 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCoreActivator.cpp mitkCoreObjectFactoryBase.cpp mitkCoreObjectFactory.cpp mitkCoreServices.cpp mitkException.cpp Algorithms/mitkBaseDataSource.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkCompositePixelValueToString.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkExtractSliceFilter2.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp Algorithms/mitkTemporalJoinImagesFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp + Controllers/mitkCrosshairManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAnatomicalStructureColorPresets.cpp DataManagement/mitkArbitraryTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkGenericIDRelationRule.cpp DataManagement/mitkIdentifiable.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkIPersistenceService.cpp DataManagement/mitkIPropertyAliases.cpp DataManagement/mitkIPropertyDescriptions.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp DataManagement/mitkIPropertyOwner.cpp DataManagement/mitkIPropertyPersistence.cpp DataManagement/mitkIPropertyProvider.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDataUID.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateFunction.cpp DataManagement/mitkNodePredicateGeometry.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateDataProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNodePredicateSubGeometry.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyKeyPath.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyNameHelper.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkPropertyPersistence.cpp DataManagement/mitkPropertyPersistenceInfo.cpp DataManagement/mitkPropertyRelationRuleBase.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkScaleOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkSourceImageRelationRule.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTemporoSpatialStringProperty.cpp DataManagement/mitkUIDManipulator.cpp DataManagement/mitkVector.cpp DataManagement/mitkVectorProperty.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkIPropertyRelations.cpp DataManagement/mitkPropertyRelations.cpp Interactions/mitkAction.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayActionEventBroadcast.cpp Interactions/mitkDisplayActionEventFunctions.cpp Interactions/mitkDisplayActionEventHandler.cpp Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp Interactions/mitkDisplayActionEventHandlerStd.cpp Interactions/mitkDisplayActionEventHandlerSynchronized.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionSchemeSwitcher.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkGeometryDataReaderService.cpp IO/mitkGeometryDataWriterService.cpp IO/mitkImageGenerator.cpp IO/mitkImageVtkLegacyIO.cpp IO/mitkImageVtkXmlIO.cpp IO/mitkIMimeTypeProvider.cpp IO/mitkIOConstants.cpp IO/mitkIOMimeTypes.cpp IO/mitkIOUtil.cpp IO/mitkItkImageIO.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkLegacyFileReaderService.cpp IO/mitkLegacyFileWriterService.cpp IO/mitkLocaleSwitch.cpp IO/mitkLog.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkProportionalTimeGeometryToXML.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkUtf8Util.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkPreferenceListReaderOptionsFunctor.cpp IO/mitkIOMetaInformationPropertyConstants.cpp Rendering/mitkAbstractAnnotationRenderer.cpp Rendering/mitkAnnotationUtils.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkMapper.cpp Rendering/mitkAnnotation.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfigMITKBase.xml Interactions/DisplayConfigPACSBase.xml Interactions/DisplayConfigCrosshair.xml Interactions/DisplayConfigRotation.xml Interactions/DisplayConfigActivateCoupling.xml Interactions/DisplayConfigSwivel.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigBlockLMB.xml Interactions/PointSet.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml mitkAnatomicalStructureColorPresets.xml ) diff --git a/Modules/Core/include/mitkCrosshairManager.h b/Modules/Core/include/mitkCrosshairManager.h new file mode 100644 index 0000000000..c428671f50 --- /dev/null +++ b/Modules/Core/include/mitkCrosshairManager.h @@ -0,0 +1,101 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#ifndef MITKCROSSHAIRMANAGER_H +#define MITKCROSSHAIRMANAGER_H + +#include + +#include +#include +#include +#include + +#include +#include + +namespace mitk +{ + /** + * \brief The CrosshairManager takes care of the correct settings for the plane geometries + * that form the crosshair. + * + * The CrosshairManager keeps track of a TimeGeometry, which is used to compute + * the three different plane geometries (axial, coronal, sagittal). + * These three plane geometries can be added to / removed from the data storage + * using this CrosshairManager. Adding / removing them to / from the data storage + * will change the rendering behavior for the crosshair - only data nodes + * inside the data storage will be rendered. + * + * + */ + class MITKCORE_EXPORT CrosshairManager : public itk::Object + { + public: + + mitkClassMacroItkParent(CrosshairManager, itk::Object); + mitkNewMacro2Param(Self, DataStorage*, BaseRenderer*); + + itkSetObjectMacro(DataStorage, DataStorage); + itkSetObjectMacro(BaseRenderer, BaseRenderer); + + /** + * \brief Set the input time geometry out of which the oriented geometries will be created. + */ + void ComputeOrientedTimeGeometries(const TimeGeometry* geometry); + + void SetCrosshairPosition(const Point3D& selectedPoint); + Point3D GetCrosshairPosition() const; + + void SetCrosshairVisibility(bool visible); + bool GetCrosshairVisibility() const; + + void AddPlanesToDataStorage(); + void RemovePlanesFromDataStorage(); + + protected: + + CrosshairManager(DataStorage* dataStorage, BaseRenderer* baseRenderer); + ~CrosshairManager(); + + void InitializePlaneProperties(DataNode::Pointer planeNode, const std::string& planeName); + void InitializePlaneData(DataNode::Pointer planeNode, const TimeGeometry* timeGeometry, unsigned int& slice); + void SetCrosshairPosition(const Point3D& selectedPoint, + DataNode::Pointer planeNode, + const TimeGeometry* timeGeometry, + unsigned int& slice); + void AddPlaneToDataStorage(DataNode::Pointer planeNode, DataNode::Pointer parent); + + DataStorage* m_DataStorage; + BaseRenderer* m_BaseRenderer; + + TimeGeometry::ConstPointer m_InputTimeGeometry; + TimeGeometry::Pointer m_AxialTimeGeometry; + TimeGeometry::Pointer m_CoronalTimeGeometry; + TimeGeometry::Pointer m_SagittalTimeGeometry; + + unsigned int m_AxialSlice; + unsigned int m_CoronalSlice; + unsigned int m_SagittalSlice; + + /** + * @brief The 3 helper objects which contain the plane geometry. + */ + DataNode::Pointer m_AxialPlaneNode; + DataNode::Pointer m_CoronalPlaneNode; + DataNode::Pointer m_SagittalPlaneNode; + DataNode::Pointer m_ParentNodeForGeometryPlanes; + + }; +} // namespace mitk + +#endif // MITKCROSSHAIRMANAGER_H diff --git a/Modules/Core/src/Controllers/mitkCrosshairManager.cpp b/Modules/Core/src/Controllers/mitkCrosshairManager.cpp new file mode 100644 index 0000000000..61672b2ed8 --- /dev/null +++ b/Modules/Core/src/Controllers/mitkCrosshairManager.cpp @@ -0,0 +1,344 @@ +/*============================================================================ + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center (DKFZ) +All rights reserved. + +Use of this source code is governed by a 3-clause BSD license that can be +found in the LICENSE file. + +============================================================================*/ + +#include "mitkCrosshairManager.h" + +#include +#include +#include +#include +#include +#include + +mitk::CrosshairManager::CrosshairManager(DataStorage* dataStorage, BaseRenderer* baseRenderer) + : m_DataStorage(dataStorage) + , m_BaseRenderer(baseRenderer) + , m_InputTimeGeometry() + , m_AxialTimeGeometry() + , m_CoronalTimeGeometry() + , m_SagittalTimeGeometry() +{ + m_AxialPlaneNode = mitk::DataNode::New(); + m_CoronalPlaneNode = mitk::DataNode::New(); + m_SagittalPlaneNode = mitk::DataNode::New(); + + std::string rendererName = std::string(m_BaseRenderer->GetName()); + this->InitializePlaneProperties(m_AxialPlaneNode, std::string(rendererName + "axial.plane")); + this->InitializePlaneProperties(m_CoronalPlaneNode, std::string(rendererName + "coronal.plane")); + this->InitializePlaneProperties(m_SagittalPlaneNode, std::string(rendererName + "sagittal.plane")); + + m_ParentNodeForGeometryPlanes = mitk::DataNode::New(); + m_ParentNodeForGeometryPlanes->SetProperty("name", mitk::StringProperty::New(rendererName)); + m_ParentNodeForGeometryPlanes->SetProperty("helper object", mitk::BoolProperty::New(true)); +} + +mitk::CrosshairManager::~CrosshairManager() +{ + this->RemovePlanesFromDataStorage(); +} + +void mitk::CrosshairManager::ComputeOrientedTimeGeometries(const TimeGeometry* geometry) +{ + if (nullptr != geometry) + { + if (geometry->GetBoundingBoxInWorld()->GetDiagonalLength2() < eps) + { + itkWarningMacro("setting an empty bounding-box"); + geometry = nullptr; + } + } + + if (m_InputTimeGeometry == geometry) + { + return; + } + + m_InputTimeGeometry = geometry; + + if (m_InputTimeGeometry.IsNull()) + { + return; + } + + if (0 == m_InputTimeGeometry->CountTimeSteps()) + { + return; + } + + try + { + m_AxialTimeGeometry = SliceNavigationHelper::CreateOrientedTimeGeometry( + m_InputTimeGeometry, PlaneGeometry::Axial, false, false, true); + m_CoronalTimeGeometry = SliceNavigationHelper::CreateOrientedTimeGeometry( + m_InputTimeGeometry, PlaneGeometry::Coronal, false, true, false); + m_SagittalTimeGeometry = SliceNavigationHelper::CreateOrientedTimeGeometry( + m_InputTimeGeometry, PlaneGeometry::Sagittal, true, true, false); + } + catch (const mitk::Exception& e) + { + MITK_ERROR << "Unable to create oriented time geometries\n" + << "Reason: " << e.GetDescription(); + } + + this->InitializePlaneData(m_AxialPlaneNode, m_AxialTimeGeometry, m_AxialSlice); + this->InitializePlaneData(m_CoronalPlaneNode, m_CoronalTimeGeometry, m_CoronalSlice); + this->InitializePlaneData(m_SagittalPlaneNode, m_SagittalTimeGeometry, m_SagittalSlice); + + RenderingManager::GetInstance()->RequestUpdate(m_BaseRenderer->GetRenderWindow()); +} + +void mitk::CrosshairManager::SetCrosshairPosition(const Point3D& selectedPoint) +{ + if (m_AxialPlaneNode.IsNull() || m_CoronalPlaneNode.IsNull() || m_SagittalPlaneNode.IsNull()) + { + return; + } + + if (m_AxialTimeGeometry.IsNull() || m_CoronalTimeGeometry.IsNull() || m_SagittalTimeGeometry.IsNull()) + { + return; + } + + this->SetCrosshairPosition(selectedPoint, m_AxialPlaneNode, m_AxialTimeGeometry, m_AxialSlice); + this->SetCrosshairPosition(selectedPoint, m_CoronalPlaneNode, m_CoronalTimeGeometry, m_CoronalSlice); + this->SetCrosshairPosition(selectedPoint, m_SagittalPlaneNode, m_SagittalTimeGeometry, m_SagittalSlice); +} + +mitk::Point3D mitk::CrosshairManager::GetCrosshairPosition() const +{ + if (m_InputTimeGeometry.IsNull()) + { + // return null-point since we don't show the crosshair anyway + return Point3D(0.0); + } + + Point3D point = m_InputTimeGeometry->GetCenterInWorld(); + + PlaneGeometry* axialPlaneGeometry = nullptr; + PlaneGeometry* coronalPlaneGeometry = nullptr; + PlaneGeometry* sagittalPlaneGeometry = nullptr; + + // get the currently selected time point + auto selectedTimePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + try + { + axialPlaneGeometry = + SliceNavigationHelper::GetCurrentPlaneGeometry(m_AxialTimeGeometry, selectedTimePoint, m_AxialSlice); + coronalPlaneGeometry = + SliceNavigationHelper::GetCurrentPlaneGeometry(m_CoronalTimeGeometry, selectedTimePoint, m_CoronalSlice); + sagittalPlaneGeometry = + SliceNavigationHelper::GetCurrentPlaneGeometry(m_SagittalTimeGeometry, selectedTimePoint, m_SagittalSlice); + } + catch (const mitk::Exception& e) + { + MITK_ERROR << "Unable to get plane geometries. Using default center point.\n" + << "Reason: " << e.GetDescription(); + } + + Line3D line; + if (nullptr != axialPlaneGeometry && nullptr != coronalPlaneGeometry && + axialPlaneGeometry->IntersectionLine(coronalPlaneGeometry, line)) + { + if (nullptr != sagittalPlaneGeometry && sagittalPlaneGeometry->IntersectionPoint(line, point)) + { + return point; + } + } + + // return input geometry center point if no intersection point was found + return point; +} + +void mitk::CrosshairManager::SetCrosshairVisibility(bool visible) +{ + if (m_AxialPlaneNode.IsNull() || m_CoronalPlaneNode.IsNull() || m_SagittalPlaneNode.IsNull()) + { + return; + } + + m_AxialPlaneNode->SetVisibility(visible, m_BaseRenderer); + m_CoronalPlaneNode->SetVisibility(visible, m_BaseRenderer); + m_SagittalPlaneNode->SetVisibility(visible, m_BaseRenderer); +} + +bool mitk::CrosshairManager::GetCrosshairVisibility() const +{ + if (m_AxialPlaneNode.IsNull() || m_CoronalPlaneNode.IsNull() || m_SagittalPlaneNode.IsNull()) + { + return false; + } + + bool axialVisibility = false; + if (m_AxialPlaneNode->GetVisibility(axialVisibility, m_BaseRenderer)) + { + bool coronalVisibility = false; + if (m_CoronalPlaneNode->GetVisibility(coronalVisibility, m_BaseRenderer)) + { + bool sagittalVisibility = false; + if (m_SagittalPlaneNode->GetVisibility(sagittalVisibility, m_BaseRenderer)) + { + if (axialVisibility == coronalVisibility && coronalVisibility == sagittalVisibility) + { + return axialVisibility; + } + } + } + } + + mitkThrow() << "Invalid state of plane visibility."; +} + +void mitk::CrosshairManager::AddPlanesToDataStorage() +{ + if (nullptr == m_DataStorage) + { + return; + } + + if (m_AxialPlaneNode.IsNull() || m_CoronalPlaneNode.IsNull() + || m_SagittalPlaneNode.IsNull() || m_ParentNodeForGeometryPlanes.IsNull()) + { + return; + } + + this->AddPlaneToDataStorage(m_ParentNodeForGeometryPlanes, nullptr); + this->AddPlaneToDataStorage(m_AxialPlaneNode, m_ParentNodeForGeometryPlanes); + this->AddPlaneToDataStorage(m_CoronalPlaneNode, m_ParentNodeForGeometryPlanes); + this->AddPlaneToDataStorage(m_SagittalPlaneNode, m_ParentNodeForGeometryPlanes); +} + +void mitk::CrosshairManager::RemovePlanesFromDataStorage() +{ + if (nullptr == m_DataStorage) + { + return; + } + + if (m_AxialPlaneNode.IsNotNull() && m_CoronalPlaneNode.IsNotNull() + && m_SagittalPlaneNode.IsNotNull() && m_ParentNodeForGeometryPlanes.IsNotNull()) + { + m_DataStorage->Remove(m_AxialPlaneNode); + m_DataStorage->Remove(m_CoronalPlaneNode); + m_DataStorage->Remove(m_SagittalPlaneNode); + m_DataStorage->Remove(m_ParentNodeForGeometryPlanes); + } +} + +void mitk::CrosshairManager::InitializePlaneProperties(DataNode::Pointer planeNode, const std::string& planeName) +{ + planeNode->GetPropertyList()->SetProperty("layer", mitk::IntProperty::New(1000)); + planeNode->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New()); + planeNode->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(5)); + planeNode->SetProperty("Crosshair.Gap Size", mitk::IntProperty::New(32)); + + // set the crosshair only visible for this specific renderer + planeNode->SetVisibility(false); + planeNode->SetVisibility(true, m_BaseRenderer); + planeNode->SetProperty("name", mitk::StringProperty::New(planeName)); + planeNode->SetProperty("helper object", mitk::BoolProperty::New(true)); +} + +void mitk::CrosshairManager::InitializePlaneData(DataNode::Pointer planeNode, const TimeGeometry* timeGeometry, unsigned int& slice) +{ + if (planeNode.IsNull()) + { + return; + } + + if (nullptr == timeGeometry) + { + return; + } + + // get the BaseGeometry of the selected time point + auto selectedTimePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + auto currentGeometry = timeGeometry->GetGeometryForTimePoint(selectedTimePoint); + if (nullptr == currentGeometry) + { + // time point not valid for the time geometry + mitkThrow() << "Cannot extract a base geometry. A time point is selected that is not covered by" + << "the given time geometry. Selected time point: " << selectedTimePoint; + } + + const auto* slicedGeometry = dynamic_cast(currentGeometry.GetPointer()); + if (nullptr == slicedGeometry) + { + return; + } + + slice = slicedGeometry->GetSlices() / 2; // center slice + PlaneGeometryData::Pointer planeData = PlaneGeometryData::New(); + planeData->SetPlaneGeometry(slicedGeometry->GetPlaneGeometry(slice)); + planeNode->SetData(planeData); +} + +void mitk::CrosshairManager::SetCrosshairPosition(const Point3D& selectedPoint, + DataNode::Pointer planeNode, + const TimeGeometry* timeGeometry, + unsigned int& slice) +{ + PlaneGeometryData::Pointer planeData = PlaneGeometryData::New(); + + int selectedSlice = -1; + try + { + selectedSlice = SliceNavigationHelper::SelectSliceByPoint(timeGeometry, selectedPoint); + } + catch (const mitk::Exception& e) + { + MITK_ERROR << "Unable to select a slice by the given point " << selectedPoint << "\n" + << "Reason: " << e.GetDescription(); + } + + if (-1 == selectedSlice) + { + return; + } + + slice = selectedSlice; + mitk::PlaneGeometry* planeGeometry = nullptr; + // get the currently selected time point + auto selectedTimePoint = RenderingManager::GetInstance()->GetTimeNavigationController()->GetSelectedTimePoint(); + try + { + planeGeometry = SliceNavigationHelper::GetCurrentPlaneGeometry(timeGeometry, selectedTimePoint, slice); + } + catch (const mitk::Exception& e) + { + MITK_ERROR << "Unable to get plane geometries\n" + << "Reason: " << e.GetDescription(); + } + + if (nullptr == planeGeometry) + { + return; + } + + planeData->SetPlaneGeometry(planeGeometry); + planeNode->SetData(planeData); +} + +void mitk::CrosshairManager::AddPlaneToDataStorage(DataNode::Pointer planeNode, DataNode::Pointer parent) +{ + if (!m_DataStorage->Exists(planeNode) + && (nullptr == parent || m_DataStorage->Exists(parent))) + { + try + { + m_DataStorage->Add(planeNode, parent); + } + catch (std::invalid_argument& /*e*/) + { + return; + } + } +}