diff --git a/CMake/FindDCMTK.cmake b/CMake/FindDCMTK.cmake index 1ebd82cb10..7996817cd4 100644 --- a/CMake/FindDCMTK.cmake +++ b/CMake/FindDCMTK.cmake @@ -1,180 +1,183 @@ # adapted version of FindDCMTK, better suited for super-builds # - find DCMTK libraries and applications # # DCMTK_INCLUDE_DIRS - Directories to include to use DCMTK # DCMTK_LIBRARIES - Files to link against to use DCMTK # DCMTK_FOUND - If false, don't try to use DCMTK # DCMTK_DIR - (optional) Source directory for DCMTK # # DCMTK_DIR can be used to make it simpler to find the various include # directories and compiled libraries if you've just compiled it in the # source tree. Just set it to the root of the tree where you extracted # the source (default to /usr/include/dcmtk/) #============================================================================= # Copyright 2004-2009 Kitware, Inc. # Copyright 2009-2010 Mathieu Malaterre # Copyright 2010 Thomas Sondergaard # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distributed this file outside of CMake, substitute the full # License text for the above reference.) # # Written for VXL by Amitha Perera. # Upgraded for GDCM by Mathieu Malaterre. # Modified for EasyViz by Thomas Sondergaard. # # prefer DCMTK_DIR over default system paths like /usr/lib set(CMAKE_PREFIX_PATH ${DCMTK_DIR}/lib ${CMAKE_PREFIX_PATH}) # this is given to FIND_LIBRARY or FIND_PATH if(NOT DCMTK_FOUND AND NOT DCMTK_DIR) set(DCMTK_DIR "/usr/include/dcmtk/" CACHE PATH "Root of DCMTK source tree (optional).") mark_as_advanced(DCMTK_DIR) endif() # Find all libraries, store debug and release separately foreach(lib dcmpstat dcmsr dcmsign dcmtls dcmqrdb dcmnet dcmjpeg dcmimage dcmimgle dcmdata + dcmrt oflog ofstd ijg12 ijg16 ijg8 ) # Find Release libraries find_library(DCMTK_${lib}_LIBRARY_RELEASE ${lib} PATHS ${DCMTK_DIR}/${lib}/libsrc ${DCMTK_DIR}/${lib}/libsrc/Release ${DCMTK_DIR}/${lib}/Release ${DCMTK_DIR}/lib ${DCMTK_DIR}/lib/Release ${DCMTK_DIR}/dcmjpeg/lib${lib}/Release NO_DEFAULT_PATH ) # Find Debug libraries find_library(DCMTK_${lib}_LIBRARY_DEBUG ${lib} PATHS ${DCMTK_DIR}/${lib}/libsrc ${DCMTK_DIR}/${lib}/libsrc/Debug ${DCMTK_DIR}/${lib}/Debug ${DCMTK_DIR}/lib ${DCMTK_DIR}/lib/Debug ${DCMTK_DIR}/dcmjpeg/lib${lib}/Debug NO_DEFAULT_PATH ) mark_as_advanced(DCMTK_${lib}_LIBRARY_RELEASE) mark_as_advanced(DCMTK_${lib}_LIBRARY_DEBUG) # Add libraries to variable according to build type set(DCMTK_${lib}_LIBRARY) if(DCMTK_${lib}_LIBRARY_RELEASE) list(APPEND DCMTK_LIBRARIES optimized ${DCMTK_${lib}_LIBRARY_RELEASE}) list(APPEND DCMTK_${lib}_LIBRARY optimized ${DCMTK_${lib}_LIBRARY_RELEASE}) endif() if(DCMTK_${lib}_LIBRARY_DEBUG) list(APPEND DCMTK_LIBRARIES debug ${DCMTK_${lib}_LIBRARY_DEBUG}) list(APPEND DCMTK_${lib}_LIBRARY debug ${DCMTK_${lib}_LIBRARY_DEBUG}) endif() endforeach() set(DCMTK_config_TEST_HEADER osconfig.h) set(DCMTK_dcmdata_TEST_HEADER dctypes.h) set(DCMTK_dcmimage_TEST_HEADER dicoimg.h) set(DCMTK_dcmimgle_TEST_HEADER dcmimage.h) set(DCMTK_dcmjpeg_TEST_HEADER djdecode.h) set(DCMTK_dcmnet_TEST_HEADER assoc.h) set(DCMTK_dcmpstat_TEST_HEADER dcmpstat.h) set(DCMTK_dcmqrdb_TEST_HEADER dcmqrdba.h) set(DCMTK_dcmsign_TEST_HEADER sicert.h) set(DCMTK_dcmsr_TEST_HEADER dsrtree.h) set(DCMTK_dcmtls_TEST_HEADER tlslayer.h) set(DCMTK_ofstd_TEST_HEADER ofstdinc.h) +set(DCMTK_dcmrt_TEST_HEADER drtstrct.h) foreach(dir config dcmdata dcmimage dcmimgle dcmjpeg dcmnet dcmpstat dcmqrdb dcmsign dcmsr dcmtls + dcmrt ofstd) find_path(DCMTK_${dir}_INCLUDE_DIR ${DCMTK_${dir}_TEST_HEADER} PATHS ${DCMTK_DIR}/${dir}/include ${DCMTK_DIR}/${dir} ${DCMTK_DIR}/include/dcmtk/${dir} ${DCMTK_DIR}/include/${dir}) mark_as_advanced(DCMTK_${dir}_INCLUDE_DIR) #message("** DCMTKs ${dir} found at ${DCMTK_${dir}_INCLUDE_DIR}") if(DCMTK_${dir}_INCLUDE_DIR) list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_${dir}_INCLUDE_DIR}) endif() endforeach() if(WIN32) list(APPEND DCMTK_LIBRARIES netapi32 wsock32) endif() if(DCMTK_ofstd_INCLUDE_DIR) get_filename_component(DCMTK_dcmtk_INCLUDE_DIR ${DCMTK_ofstd_INCLUDE_DIR} PATH CACHE) list(APPEND DCMTK_INCLUDE_DIRS ${DCMTK_dcmtk_INCLUDE_DIR}) mark_as_advanced(DCMTK_dcmtk_INCLUDE_DIR) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(DCMTK DEFAULT_MSG DCMTK_config_INCLUDE_DIR DCMTK_ofstd_INCLUDE_DIR DCMTK_ofstd_LIBRARY DCMTK_dcmdata_INCLUDE_DIR DCMTK_dcmdata_LIBRARY DCMTK_dcmimgle_INCLUDE_DIR DCMTK_dcmimgle_LIBRARY ) # Compatibility: This variable is deprecated set(DCMTK_INCLUDE_DIR ${DCMTK_INCLUDE_DIRS}) diff --git a/Core/Code/DataManagement/mitkRenderingModeProperty.cpp b/Core/Code/DataManagement/mitkRenderingModeProperty.cpp index b943aedd83..03df9590a1 100644 --- a/Core/Code/DataManagement/mitkRenderingModeProperty.cpp +++ b/Core/Code/DataManagement/mitkRenderingModeProperty.cpp @@ -1,72 +1,73 @@ /*=================================================================== 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 "mitkRenderingModeProperty.h" mitk::RenderingModeProperty::RenderingModeProperty( ) { this->AddRenderingModes(); this->SetValue( LEVELWINDOW_COLOR ); } mitk::RenderingModeProperty::RenderingModeProperty( const IdType& value ) { this->AddRenderingModes(); if ( IsValidEnumerationValue( value ) ) { this->SetValue( value ) ; } else MITK_WARN << "Warning: invalid image rendering mode"; } mitk::RenderingModeProperty::RenderingModeProperty( const std::string& value ) { this->AddRenderingModes(); if ( IsValidEnumerationValue( value ) ) { this->SetValue( value ); } else MITK_WARN << "Invalid image rendering mode"; } int mitk::RenderingModeProperty::GetRenderingMode() { return static_cast( this->GetValueAsId() ); } void mitk::RenderingModeProperty::AddRenderingModes() { AddEnum( "LevelWindow_Color", LEVELWINDOW_COLOR ); AddEnum( "LookupTable_LevelWindow_Color", LOOKUPTABLE_LEVELWINDOW_COLOR ); AddEnum( "ColorTransferFunction_LevelWindow_Color", COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR ); AddEnum( "LookupTable_Color", LOOKUPTABLE_COLOR ); AddEnum( "ColorTransferFunction_Color", COLORTRANSFERFUNCTION_COLOR ); + AddEnum( "IsoDoseShader_Color", ISODOSESHADER_COLOR ); } bool mitk::RenderingModeProperty::AddEnum( const std::string& name, const IdType& id ) { return Superclass::AddEnum( name, id ); } itk::LightObject::Pointer mitk::RenderingModeProperty::InternalClone() const { itk::LightObject::Pointer result(new Self(*this)); result->UnRegister(); return result; } diff --git a/Core/Code/DataManagement/mitkRenderingModeProperty.h b/Core/Code/DataManagement/mitkRenderingModeProperty.h index 7608d6d353..c2d47efb9e 100644 --- a/Core/Code/DataManagement/mitkRenderingModeProperty.h +++ b/Core/Code/DataManagement/mitkRenderingModeProperty.h @@ -1,166 +1,167 @@ /*=================================================================== 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 _MITK_RENDERING_MODE_PROPERTY__H_ #define _MITK_RENDERING_MODE_PROPERTY__H_ #include "mitkEnumerationProperty.h" namespace mitk { #ifdef _MSC_VER # pragma warning(push) # pragma warning(disable: 4522) #endif /** * Encapsulates the enumeration for rendering modes. The property human-readable name (which is * used in the mitkWorkbench inside the Property View) is "Image Rendering.Mode". This property * affects rendering of images and is used inside the mitkImageVtkMapper2D to define which * rendering mode is applied to images. * Valid values are: * * \li LEVELWINDOW_COLOR: Level window and color will be applied to the image. * Our default level-window (sometimes referred to as window-level by other sources) setup for a test image looks like this: * \image html ExampleLevelWindowColor.png * This image can be reproduced with the mitkImageVtkMapper2DColorTest or mitkImageVtkMapper2DLevelWindowTest. * If "Image Rendering.Mode" is set to LEVELWINDOW_COLOR inside the mitkWorkbench, the level window slider will change * the rendering of the image. That means it will change the values of an internally used default lookup table. * Note, the level window slider changes the property "levelwindow" which modifies the range of * the internally used default lookup table. There is no way to directly modify the default lookup table. * In case you want to create a lookup table, use any LOOKUPTABLE mode as "Image Rendering.Mode". * This mode will apply the "color" property. The default color is white. If you change the "color" * property to yellow, the test image will be rendered like this: * \image html ExampleColorYellow.png * This image can be reproduced with the mitkImageVtkMapper2DColorTest. * * \li LOOKUPTABLE_LEVELWINDOW_COLOR: A lookup table, level window and color will be applied to the image. * As lookup table, the table object supplied by the property "LookupTable" will be used. If the user does not * supply any lookup table, a default rainbow-like lookup table will be used instead. This lookup table * will be influenced by the property "levelwindow" and the actor will be colored by the * "color" property. * Our test image with a lookup table mapping everything from red to blue looks like this: * \image html ExampleLookupTable.png * This image can be reproduced with the mitkImageVtkMapper2DLookupTableTest. Check this test code for an example how * to apply a lookup table to an image. * \note Changing a lookup table via the "levelwindow" property can be unintuitive and unwanted since the * level window slider will overwrite the range of the lookup table. Use LOOKUPTABLE_COLOR if you * don't want your lookuptable to be influenced by the "levelwindow" property. * * \li COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR: A color transfer function, level window and color will be applied to the image. * Very similar mode to LOOKUPTABLE_LEVELWINDOW_COLOR. Instead of the lookup table a color transfer function will be used. * Color transfer functions are useful to colorize floating point images and allow sometimes more flexibility than * a lookup table. The "Image Rendering.Transfer Function" property defines the transfer function. Our test image * with a transfer function mapping everything from to red, green and blue looks like this: * \image html ExampleTransferFunction.png * This image can be reproduced with the mitkImageVtkMapper2DTransferFunctionTest. Check the test code for * an example how to define a transfer function for an image. This transfer function * will be influenced by the property "levelwindow" and the actor will be colored by the * "color" property. * \note Changing a transfer function table via the "levelwindow" property can be unintuitive and unwanted since * the level window slider will overwrite the.Use COLORTRANSFERFUNCTION_COLOR if you don't want your transfer * function to be influenced by the level window. * * \li LOOKUPTABLE_COLOR: A lookup table and color will be applied to the image. * Similar mode to LOOKUPTABLE_LEVELWINDOW_COLOR, except that the "levelwindow" property will not * modify the range of the lookup table. * * \li COLORTRANSFERFUNCTION_COLOR: A color trans ferfunction and color will be applied to the image. * Similar mode to COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR, except that the "levelwindow" property will not * modify the range of the transfer function. * * The order is given by the names (e.g. LOOKUPTABLE_COLOR applies first a lookup table and next a color). * Currently, there is no GUI (in mitkWorkbench) support for controlling lookup tables or transfer functions. * This has to be done by the programmer. Color and level window are controlled by color widget and level window slider. * Currently, the color is always applied. We do not set the color to white, if the user changes the mode. We assume * that users who change the mode know that a previously set color will still be applied (on top of the respective mode). * See VTK documentation for examples how to use vtkTransferfunction and vtkLookupTable. */ class MITK_CORE_EXPORT RenderingModeProperty : public EnumerationProperty { public: mitkClassMacro( RenderingModeProperty, EnumerationProperty ); itkFactorylessNewMacro(Self) itkCloneMacro(Self) mitkNewMacro1Param(RenderingModeProperty, const IdType&); mitkNewMacro1Param(RenderingModeProperty, const std::string&); //Never (!) change this without adaptation of mitkLevelWindowManagerTest::VerifyRenderingModes and mitkLevelWindowManagerTest::TestLevelWindowSliderVisibility ! enum ImageRenderingMode { LEVELWINDOW_COLOR = 0, LOOKUPTABLE_LEVELWINDOW_COLOR = 1, COLORTRANSFERFUNCTION_LEVELWINDOW_COLOR = 2, LOOKUPTABLE_COLOR = 3, - COLORTRANSFERFUNCTION_COLOR = 4 + COLORTRANSFERFUNCTION_COLOR = 4, + ISODOSESHADER_COLOR = 5 // Default = LEVELWINDOW_COLOR; }; /** * Returns the current rendering mode */ virtual int GetRenderingMode(); using BaseProperty::operator=; protected: /** Sets rendering type to default (VTK_RAY_CAST_COMPOSITE_FUNCTION). */ RenderingModeProperty( ); /** * Constructor. Sets rendering type to the given value. */ RenderingModeProperty( const IdType& value ); /** * Constructor. Sets rendering type to the given value. */ RenderingModeProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid rendering types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the default enumeration types. */ virtual void AddRenderingModes(); private: // purposely not implemented RenderingModeProperty& operator=(const RenderingModeProperty&); virtual itk::LightObject::Pointer InternalClone() const; }; #ifdef _MSC_VER # pragma warning(pop) #endif } // end of namespace mitk #endif diff --git a/Core/Code/files.cmake b/Core/Code/files.cmake index 3525e7084f..bcc2ab8d80 100644 --- a/Core/Code/files.cmake +++ b/Core/Code/files.cmake @@ -1,406 +1,405 @@ set(H_FILES Algorithms/itkImportMitkImageContainer.h Algorithms/itkImportMitkImageContainer.txx Algorithms/itkMITKScalarImageToHistogramGenerator.h Algorithms/itkMITKScalarImageToHistogramGenerator.txx Algorithms/mitkInstantiateAccessFunctions.h Algorithms/mitkPixelTypeList.h Algorithms/mitkPPArithmeticDec.h Algorithms/mitkPPArgCount.h Algorithms/mitkPPCat.h Algorithms/mitkPPConfig.h Algorithms/mitkPPControlExprIIf.h Algorithms/mitkPPControlIf.h Algorithms/mitkPPControlIIf.h Algorithms/mitkPPDebugError.h Algorithms/mitkPPDetailAutoRec.h Algorithms/mitkPPDetailDMCAutoRec.h Algorithms/mitkPPExpand.h Algorithms/mitkPPFacilitiesEmpty.h Algorithms/mitkPPFacilitiesExpand.h Algorithms/mitkPPLogicalBool.h Algorithms/mitkPPRepetitionDetailDMCFor.h Algorithms/mitkPPRepetitionDetailEDGFor.h Algorithms/mitkPPRepetitionDetailFor.h Algorithms/mitkPPRepetitionDetailMSVCFor.h Algorithms/mitkPPRepetitionFor.h Algorithms/mitkPPSeqElem.h Algorithms/mitkPPSeqForEach.h Algorithms/mitkPPSeqForEachProduct.h Algorithms/mitkPPSeq.h Algorithms/mitkPPSeqEnum.h Algorithms/mitkPPSeqSize.h Algorithms/mitkPPSeqToTuple.h Algorithms/mitkPPStringize.h Algorithms/mitkPPTupleEat.h Algorithms/mitkPPTupleElem.h Algorithms/mitkPPTupleRem.h Algorithms/mitkClippedSurfaceBoundsCalculator.h Algorithms/mitkExtractSliceFilter.h Algorithms/mitkConvert2Dto3DImageFilter.h Algorithms/mitkPlaneClipping.h Common/mitkCommon.h Common/mitkExceptionMacro.h DataManagement/mitkProportionalTimeGeometry.h DataManagement/mitkTimeGeometry.h DataManagement/mitkImageAccessByItk.h DataManagement/mitkImageCast.h DataManagement/mitkImagePixelAccessor.h DataManagement/mitkImagePixelReadAccessor.h DataManagement/mitkImagePixelWriteAccessor.h DataManagement/mitkImageReadAccessor.h DataManagement/mitkImageWriteAccessor.h DataManagement/mitkITKImageImport.h DataManagement/mitkITKImageImport.txx DataManagement/mitkImageToItk.h DataManagement/mitkShaderProperty.h DataManagement/mitkImageToItk.txx DataManagement/mitkTimeSlicedGeometry.h # Deprecated, empty for compatibilty reasons. DataManagement/mitkPropertyListReplacedObserver.cpp Interactions/mitkEventMapperAddOn.h Interfaces/mitkIDataNodeReader.h Rendering/mitkLocalStorageHandler.h Rendering/Colortables/HotIron.h Rendering/Colortables/Jet.h Rendering/Colortables/PET20.h Rendering/Colortables/PETColor.h IO/mitkPixelTypeTraits.h ) set(CPP_FILES Algorithms/mitkBaseDataSource.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkGeometry2DDataToSurfaceFilter.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.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/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkCoreActivator.cpp Controllers/mitkFocusManager.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkSlicesRotator.cpp Controllers/mitkSlicesSwiveller.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkInteractorCameraController.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataStorage.cpp # DataManagement/mitkDataTree.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataNodeFactory.cpp # DataManagement/mitkDataTreeStorage.cpp DataManagement/mitkDisplayGeometry.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkGeometry2D.cpp DataManagement/mitkGeometry2DData.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkLandmarkBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModeOperation.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStateTransitionOperation.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkVector.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkMaterial.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkShaderProperty.cpp Interactions/mitkAction.cpp Interactions/mitkAffineInteractor.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCoordinateSupplier.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkDisplayPositionEvent.cpp # Interactions/mitkDisplayVectorInteractorLevelWindow.cpp # legacy, prob even now unneeded # Interactions/mitkDisplayVectorInteractorScroll.cpp Interactions/mitkEvent.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventDescription.cpp Interactions/mitkEventFactory.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkEventMapper.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkGlobalInteraction.cpp Interactions/mitkInteractor.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMovePointSetInteractor.cpp Interactions/mitkMoveBaseDataInteractor.cpp Interactions/mitkNodeDepententPointSetInteractor.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkPointSetInteractor.cpp Interactions/mitkPositionEvent.cpp Interactions/mitkPositionTracker.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkState.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateEvent.cpp Interactions/mitkStateMachine.cpp Interactions/mitkStateMachineFactory.cpp Interactions/mitkTransition.cpp Interactions/mitkWheelEvent.cpp Interactions/mitkKeyEvent.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkXML2EventParser.cpp Interfaces/mitkInteractionEventObserver.cpp Interfaces/mitkIShaderRepository.cpp Interfaces/mitkIPropertyAliases.cpp Interfaces/mitkIPropertyDescriptions.cpp Interfaces/mitkIPropertyExtensions.cpp Interfaces/mitkIPropertyFilters.cpp Interfaces/mitkIPersistenceService.cpp IO/mitkBaseDataIOFactory.cpp IO/mitkCoreDataNodeReader.cpp IO/mitkDicomSeriesReader.cpp IO/mitkDicomSR_LoadDICOMScalar.cpp IO/mitkDicomSR_LoadDICOMScalar4D.cpp IO/mitkDicomSR_LoadDICOMRGBPixel.cpp IO/mitkDicomSR_LoadDICOMRGBPixel4D.cpp IO/mitkDicomSR_ImageBlockDescriptor.cpp IO/mitkDicomSR_GantryTiltInformation.cpp IO/mitkDicomSR_SliceGroupingResult.cpp IO/mitkFileReader.cpp IO/mitkFileSeriesReader.cpp IO/mitkFileWriter.cpp # IO/mitkIpPicGet.c IO/mitkImageGenerator.cpp IO/mitkImageWriter.cpp IO/mitkImageWriterFactory.cpp IO/mitkItkImageFileIOFactory.cpp IO/mitkItkImageFileReader.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkItkPictureWrite.cpp IO/mitkIOUtil.cpp IO/mitkLookupTableProperty.cpp IO/mitkOperation.cpp # IO/mitkPicFileIOFactory.cpp # IO/mitkPicFileReader.cpp # IO/mitkPicFileWriter.cpp # IO/mitkPicHelper.cpp # IO/mitkPicVolumeTimeSeriesIOFactory.cpp # IO/mitkPicVolumeTimeSeriesReader.cpp IO/mitkPixelType.cpp IO/mitkPointSetIOFactory.cpp IO/mitkPointSetReader.cpp IO/mitkPointSetWriter.cpp IO/mitkPointSetWriterFactory.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSTLFileIOFactory.cpp IO/mitkSTLFileReader.cpp IO/mitkSurfaceVtkWriter.cpp IO/mitkSurfaceVtkWriterFactory.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkVtiFileIOFactory.cpp IO/mitkVtiFileReader.cpp IO/mitkVtkImageIOFactory.cpp IO/mitkVtkImageReader.cpp IO/mitkVtkSurfaceIOFactory.cpp IO/mitkVtkSurfaceReader.cpp IO/vtkPointSetXMLParser.cpp IO/mitkLog.cpp Rendering/mitkBaseRenderer.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkRenderWindowFrame.cpp Rendering/mitkGeometry2DDataMapper2D.cpp Rendering/mitkGeometry2DDataVtkMapper3D.cpp Rendering/mitkGLMapper.cpp Rendering/mitkGradientBackground.cpp Rendering/mitkManufacturerLogo.cpp Rendering/mitkMapper.cpp Rendering/mitkPointSetGLMapper2D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkPolyDataGLMapper2D.cpp Rendering/mitkSurfaceGLMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVolumeDataVtkMapper3D.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp - Rendering/mitkOverlay.cpp Rendering/mitkVtkOverlay.cpp Rendering/mitkVtkOverlay2D.cpp Rendering/mitkVtkOverlay3D.cpp Rendering/mitkOverlayManager.cpp Rendering/mitkAbstractOverlayLayouter.cpp Rendering/mitkTextOverlay2D.cpp Rendering/mitkTextOverlay3D.cpp Rendering/mitkLabelOverlay3D.cpp Rendering/mitkOverlay2DLayouter.cpp Rendering/mitkScaleLegendOverlay Common/mitkException.cpp Common/mitkCommon.h Common/mitkCoreObjectFactoryBase.cpp Common/mitkCoreObjectFactory.cpp Common/mitkCoreServices.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml ) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 9843ea9d59..9b18c577cf 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,77 +1,79 @@ # Modules must be listed according to their dependencies set(module_dirs DataTypesExt AlgorithmsExt MapperExt IOExt Qt4Qt5TestModule SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors IpPicSupport Ext SceneSerialization GraphAlgorithms ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QmlItems QtWidgets QtWidgetsExt SegmentationUI DiffusionImaging GPGPU IGTBase IGT CameraCalibration IGTUI RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport Overlays InputDevices ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python Persistence VtkShaders + DicomRT + RTUI ) if(MITK_ENABLE_PIC_READER) list(APPEND module_dirs IpPicSupportIO) endif() set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) foreach(module_dir ${module_dirs}) add_subdirectory(${module_dir}) endforeach() if(MITK_PRIVATE_MODULES) file(GLOB all_subdirs RELATIVE ${MITK_PRIVATE_MODULES} ${MITK_PRIVATE_MODULES}/*) foreach(subdir ${all_subdirs}) string(FIND ${subdir} "." _result) if(_result EQUAL -1) if(EXISTS ${MITK_PRIVATE_MODULES}/${subdir}/CMakeLists.txt) message(STATUS "Found private module ${subdir}") add_subdirectory(${MITK_PRIVATE_MODULES}/${subdir} private_modules/${subdir}) endif() endif() endforeach() endif(MITK_PRIVATE_MODULES) diff --git a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2D.cpp b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2D.cpp index 0421c4beda..fd5e2fe0f4 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelGLMapper2D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelGLMapper2D.cpp @@ -1,106 +1,114 @@ /*=================================================================== 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 "mitkContourModelGLMapper2D.h" #include "mitkBaseRenderer.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkContourModel.h" #include "mitkContourModelSubDivisionFilter.h" #include +#include +#include #include "mitkGL.h" mitk::ContourModelGLMapper2D::ContourModelGLMapper2D() : m_SubdivisionContour(mitk::ContourModel::New()), m_InitSubdivisionCurve(true) { } mitk::ContourModelGLMapper2D::~ContourModelGLMapper2D() { } void mitk::ContourModelGLMapper2D::Paint(mitk::BaseRenderer * renderer) { BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); mitk::DataNode* dataNode = this->GetDataNode(); bool visible = true; dataNode->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; mitk::ContourModel* input = this->GetInput(); mitk::ContourModel::Pointer renderingContour = input; bool subdivision = false; dataNode->GetBoolProperty( "subdivision curve", subdivision, renderer ); if (subdivision) { if(this->m_SubdivisionContour->GetMTime() < renderingContour->GetMTime() || m_InitSubdivisionCurve) { //mitk::ContourModel::Pointer subdivContour = mitk::ContourModel::New(); mitk::ContourModelSubDivisionFilter::Pointer subdivFilter = mitk::ContourModelSubDivisionFilter::New(); subdivFilter->SetInput(input); subdivFilter->Update(); this->m_SubdivisionContour = subdivFilter->GetOutput(); m_InitSubdivisionCurve = false; } renderingContour = this->m_SubdivisionContour; } this->DrawContour(renderingContour, renderer); ls->UpdateGenerateDataTime(); } mitk::ContourModel* mitk::ContourModelGLMapper2D::GetInput(void) { return const_cast< mitk::ContourModel* >(static_cast< const mitk::ContourModel* > ( GetDataNode()->GetData() )); } void mitk::ContourModelGLMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { - node->AddProperty( "contour.color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); + node->AddProperty( "color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.segments.show", mitk::BoolProperty::New( true ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering.width", mitk::FloatProperty::New( 3.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.points.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "subdivision curve", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.project-onto-plane", mitk::BoolProperty::New( false ), renderer, overwrite ); - node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); + IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); + + if(aliases != NULL) + { + aliases->AddAlias("color", "contour.color", "ContourModel"); + } + Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper2D.cpp b/Modules/ContourModel/Rendering/mitkContourModelMapper2D.cpp index 22f2c99458..e084dc34de 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelMapper2D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelMapper2D.cpp @@ -1,392 +1,395 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include +#include +#include mitk::ContourModelMapper2D::ContourModelMapper2D() { } mitk::ContourModelMapper2D::~ContourModelMapper2D() { } const mitk::ContourModel* mitk::ContourModelMapper2D::GetInput( void ) { //convient way to get the data from the dataNode return static_cast< const mitk::ContourModel * >( GetDataNode()->GetData() ); } vtkProp* mitk::ContourModelMapper2D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Actor; } void mitk::ContourModelMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { /*++ convert the contour to vtkPolyData and set it as input for our mapper ++*/ LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::ContourModel* inputContour = static_cast< mitk::ContourModel* >( GetDataNode()->GetData() ); unsigned int timestep = renderer->GetTimeStep(); //if there's something to be rendered if( inputContour->GetNumberOfVertices(timestep) > 0) { localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour, renderer); } this->ApplyContourProperties(renderer); localStorage->m_Mapper->SetInputData(localStorage->m_OutlinePolyData); } void mitk::ContourModelMapper2D::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; //check if there is something to be rendered mitk::ContourModel* data = static_cast< mitk::ContourModel*>( GetDataNode()->GetData() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); // Check if time step is valid const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->CountTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTimeStep( renderer->GetTimeStep() ) ) ) { //clear the rendered polydata localStorage->m_Mapper->RemoveAllInputs();//SetInput(vtkSmartPointer::New()); return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } vtkSmartPointer mitk::ContourModelMapper2D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour, mitk::BaseRenderer* renderer) { unsigned int timestep = this->GetTimestep(); // Create a polydata to store everything in vtkSmartPointer resultingPolyData = vtkSmartPointer::New(); //check for the worldgeometry from the current render window mitk::PlaneGeometry* currentWorldGeometry = dynamic_cast( const_cast(renderer->GetCurrentWorldGeometry2D())); if(currentWorldGeometry) { //origin and normal of vtkPlane mitk::Point3D origin = currentWorldGeometry->GetOrigin(); mitk::Vector3D normal = currentWorldGeometry->GetNormal(); //the implicit function to slice through the polyData vtkSmartPointer plane = vtkSmartPointer::New(); plane->SetOrigin(origin[0], origin[1], origin[2]); plane->SetNormal(normal[0], normal[1], normal[2]); /* First of all convert the control points of the contourModel to vtk points * and add lines in between them */ //the points to draw vtkSmartPointer points = vtkSmartPointer::New(); //the lines to connect the points vtkSmartPointer lines = vtkSmartPointer::New(); // Create a polydata to store everything in vtkSmartPointer polyDataIn3D = vtkSmartPointer::New(); vtkSmartPointer appendPoly = vtkSmartPointer::New(); mitk::ContourModel::Pointer renderingContour = mitk::ContourModel::New(); renderingContour = inputContour; bool subdivision = false; this->GetDataNode()->GetBoolProperty( "subdivision curve", subdivision, renderer ); if (subdivision) { mitk::ContourModel::Pointer subdivContour = mitk::ContourModel::New(); mitk::ContourModelSubDivisionFilter::Pointer subdivFilter = mitk::ContourModelSubDivisionFilter::New(); subdivFilter->SetInput(inputContour); subdivFilter->Update(); subdivContour = subdivFilter->GetOutput(); if(subdivContour->GetNumberOfVertices() == 0 ) { subdivContour = inputContour; } renderingContour = subdivContour; } //iterate over all control points mitk::ContourModel::VertexIterator current = renderingContour->IteratorBegin(timestep); mitk::ContourModel::VertexIterator next = renderingContour->IteratorBegin(timestep); if(next != renderingContour->IteratorEnd(timestep)) { next++; mitk::ContourModel::VertexIterator end = renderingContour->IteratorEnd(timestep); while(next != end) { mitk::ContourModel::VertexType* currentControlPoint = *current; mitk::ContourModel::VertexType* nextControlPoint = *next; vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]); vtkIdType p2 = points->InsertNextPoint(nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]); //add the line between both contorlPoints lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); if ( currentControlPoint->IsControlPoint ) { double coordinates[3]; coordinates[0] = currentControlPoint->Coordinates[0]; coordinates[1] = currentControlPoint->Coordinates[1]; coordinates[2] = currentControlPoint->Coordinates[2]; double distance = plane->DistanceToPlane(coordinates); if(distance < 0.1) { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(1.2); sphere->SetCenter(coordinates[0], coordinates[1], coordinates[2]); sphere->Update(); appendPoly->AddInputConnection(sphere->GetOutputPort()); } } current++; next++; }//end while (it!=end) //check if last control point is enabled to draw it if ( (*current)->IsControlPoint ) { double coordinates[3]; coordinates[0] = (*current)->Coordinates[0]; coordinates[1] = (*current)->Coordinates[1]; coordinates[2] = (*current)->Coordinates[2]; double distance = plane->DistanceToPlane(coordinates); if(distance < 0.1) { vtkSmartPointer sphere = vtkSmartPointer::New(); sphere->SetRadius(1.2); sphere->SetCenter(coordinates[0], coordinates[1], coordinates[2]); sphere->Update(); appendPoly->AddInputConnection(sphere->GetOutputPort()); } } /* If the contour is closed an additional line has to be created between the very first point * and the last point */ if(renderingContour->IsClosed(timestep)) { //add a line from the last to the first control point mitk::ContourModel::VertexType* firstControlPoint = *(renderingContour->IteratorBegin(timestep)); mitk::ContourModel::VertexType* lastControlPoint = *(--(renderingContour->IteratorEnd(timestep))); vtkIdType p2 = points->InsertNextPoint(lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]); vtkIdType p1 = points->InsertNextPoint(firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]); //add the line between both contorlPoints lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); }//end if(isClosed) // Add the points to the dataset polyDataIn3D->SetPoints(points); // Add the lines to the dataset polyDataIn3D->SetLines(lines); //cut through polyData bool useCuttingPlane = false; this->GetDataNode()->GetBoolProperty( "use cutting plane", useCuttingPlane, renderer ); if (useCuttingPlane) { //slice through the data to get a 2D representation of the (possible) 3D contour //needed because currently there is no outher solution if the contour is within the plane vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetInputData(polyDataIn3D); tubeFilter->SetRadius(0.05); //cuts through vtkPolyData with a given implicit function. In our case a plane vtkSmartPointer cutter = vtkSmartPointer::New(); cutter->SetCutFunction(plane); cutter->SetInputConnection(tubeFilter->GetOutputPort()); //we want the scalars of the input - so turn off generating the scalars within vtkCutter cutter->GenerateCutScalarsOff(); cutter->Update(); //set to 2D representation of the contour resultingPolyData= cutter->GetOutput(); }//end if(project contour) else { //set to 3D polyData resultingPolyData = polyDataIn3D; } }//end if (it != end) appendPoly->AddInputData(resultingPolyData); appendPoly->Update(); //return contour with control points return appendPoly->GetOutput(); }else { //return empty polyData return resultingPolyData; } } void mitk::ContourModelMapper2D::ApplyContourProperties(mitk::BaseRenderer* renderer) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); float lineWidth(1.0); if (this->GetDataNode()->GetFloatProperty( "width", lineWidth, renderer )) { localStorage->m_Actor->GetProperty()->SetLineWidth(lineWidth); } - mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty("color", renderer)); - if(colorprop) - { - //set the color of the contour - double red = colorprop->GetColor().GetRed(); - double green = colorprop->GetColor().GetGreen(); - double blue = colorprop->GetColor().GetBlue(); - localStorage->m_Actor->GetProperty()->SetColor(red, green, blue); - } + float color[3]; + this->GetDataNode()->GetColor(color, renderer); + localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]); //make sure that directional lighting isn't used for our contour localStorage->m_Actor->GetProperty()->SetAmbient(1.0); localStorage->m_Actor->GetProperty()->SetDiffuse(0.0); localStorage->m_Actor->GetProperty()->SetSpecular(0.0); } /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/ mitk::ContourModelMapper2D::LocalStorage* mitk::ContourModelMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } mitk::ContourModelMapper2D::LocalStorage::LocalStorage() { m_Mapper = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_OutlinePolyData = vtkSmartPointer::New(); //set the mapper for the actor m_Actor->SetMapper(m_Mapper); } void mitk::ContourModelMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); node->AddProperty( "width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite ); node->AddProperty( "use cutting plane", mitk::BoolProperty::New( true ), renderer, overwrite ); node->AddProperty( "subdivision curve", mitk::BoolProperty::New( false ), renderer, overwrite ); + IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); + + if(aliases != NULL) + { + aliases->AddAlias("color", "contour.color", "ContourModel"); + } + Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp index a38fe8ee8f..ef5a654b68 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.cpp @@ -1,243 +1,242 @@ /*=================================================================== 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 #include #include #include +#include +#include mitk::ContourModelMapper3D::ContourModelMapper3D() { } mitk::ContourModelMapper3D::~ContourModelMapper3D() { } const mitk::ContourModel* mitk::ContourModelMapper3D::GetInput( void ) { //convient way to get the data from the dataNode return static_cast< const mitk::ContourModel * >( GetDataNode()->GetData() ); } vtkProp* mitk::ContourModelMapper3D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Actor; } void mitk::ContourModelMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { /* First convert the contourModel to vtkPolyData, then tube filter it and * set it input for our mapper */ LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::ContourModel* inputContour = static_cast< mitk::ContourModel* >( GetDataNode()->GetData() ); localStorage->m_OutlinePolyData = this->CreateVtkPolyDataFromContour(inputContour); this->ApplyContourProperties(renderer); //tube filter the polyData localStorage->m_TubeFilter->SetInputData(localStorage->m_OutlinePolyData); float lineWidth(1.0); if (this->GetDataNode()->GetFloatProperty( "contour.3D.width", lineWidth, renderer )) { - localStorage->m_TubeFilter->SetRadius(lineWidth); + localStorage->m_TubeFilter->SetWidth(lineWidth); }else { - localStorage->m_TubeFilter->SetRadius(0.5); + localStorage->m_TubeFilter->SetWidth(0.5); } - localStorage->m_TubeFilter->CappingOn(); - localStorage->m_TubeFilter->SetNumberOfSides(10); localStorage->m_TubeFilter->Update(); localStorage->m_Mapper->SetInputConnection(localStorage->m_TubeFilter->GetOutputPort()); } void mitk::ContourModelMapper3D::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); mitk::ContourModel* data = static_cast< mitk::ContourModel*>( GetDataNode()->GetData() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); // Check if time step is valid const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry(); if ( ( dataTimeGeometry == NULL ) || ( dataTimeGeometry->CountTimeSteps() == 0 ) || ( !dataTimeGeometry->IsValidTimeStep( renderer->GetTimeStep() ) ) || ( this->GetTimestep() == -1 ) ) { //clear the rendered polydata localStorage->m_Mapper->SetInputData(vtkSmartPointer::New()); return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } vtkSmartPointer mitk::ContourModelMapper3D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour) { unsigned int timestep = this->GetTimestep(); //the points to draw vtkSmartPointer points = vtkSmartPointer::New(); //the lines to connect the points vtkSmartPointer lines = vtkSmartPointer::New(); // Create a polydata to store everything in vtkSmartPointer polyData = vtkSmartPointer::New(); //iterate over the control points mitk::ContourModel::VertexIterator current = inputContour->IteratorBegin(timestep); mitk::ContourModel::VertexIterator next = inputContour->IteratorBegin(timestep); if(next != inputContour->IteratorEnd(timestep)) { next++; mitk::ContourModel::VertexIterator end = inputContour->IteratorEnd(timestep); while(next != end) { mitk::ContourModel::VertexType* currentControlPoint = *current; mitk::ContourModel::VertexType* nextControlPoint = *next; if( !(currentControlPoint->Coordinates[0] == nextControlPoint->Coordinates[0] && currentControlPoint->Coordinates[1] == nextControlPoint->Coordinates[1] && currentControlPoint->Coordinates[2] == nextControlPoint->Coordinates[2])) { vtkIdType p1 = points->InsertNextPoint(currentControlPoint->Coordinates[0], currentControlPoint->Coordinates[1], currentControlPoint->Coordinates[2]); vtkIdType p2 = points->InsertNextPoint(nextControlPoint->Coordinates[0], nextControlPoint->Coordinates[1], nextControlPoint->Coordinates[2]); //add the line between both contorlPoints lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } current++; next++; } if(inputContour->IsClosed(timestep)) { // If the contour is closed add a line from the last to the first control point mitk::ContourModel::VertexType* firstControlPoint = *(inputContour->IteratorBegin(timestep)); mitk::ContourModel::VertexType* lastControlPoint = *(--(inputContour->IteratorEnd(timestep))); if( lastControlPoint->Coordinates[0] != firstControlPoint->Coordinates[0] || lastControlPoint->Coordinates[1] != firstControlPoint->Coordinates[1] || lastControlPoint->Coordinates[2] != firstControlPoint->Coordinates[2]) { vtkIdType p2 = points->InsertNextPoint(lastControlPoint->Coordinates[0], lastControlPoint->Coordinates[1], lastControlPoint->Coordinates[2]); vtkIdType p1 = points->InsertNextPoint(firstControlPoint->Coordinates[0], firstControlPoint->Coordinates[1], firstControlPoint->Coordinates[2]); //add the line to the cellArray lines->InsertNextCell(2); lines->InsertCellPoint(p1); lines->InsertCellPoint(p2); } } // Add the points to the dataset polyData->SetPoints(points); // Add the lines to the dataset polyData->SetLines(lines); } return polyData; } void mitk::ContourModelMapper3D::ApplyContourProperties(mitk::BaseRenderer* renderer) { LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + float color[3]; + this->GetDataNode()->GetColor(color, renderer); - mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty - ("contour.color", renderer)); - if(colorprop) - { - //set the color of the contour - double red = colorprop->GetColor().GetRed(); - double green = colorprop->GetColor().GetGreen(); - double blue = colorprop->GetColor().GetBlue(); - localStorage->m_Actor->GetProperty()->SetColor(red, green, blue); - } + localStorage->m_Actor->GetProperty()->SetColor(color[0], color[1], color[2]); } /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/ mitk::ContourModelMapper3D::LocalStorage* mitk::ContourModelMapper3D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } mitk::ContourModelMapper3D::LocalStorage::LocalStorage() { m_Mapper = vtkSmartPointer::New(); m_Actor = vtkSmartPointer::New(); m_OutlinePolyData = vtkSmartPointer::New(); - m_TubeFilter = vtkSmartPointer::New(); + m_TubeFilter = vtkSmartPointer::New(); //set the mapper for the actor m_Actor->SetMapper(m_Mapper); } void mitk::ContourModelMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); node->AddProperty( "contour.3D.width", mitk::FloatProperty::New( 0.5 ), renderer, overwrite ); + IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); + if(aliases != NULL) + { + aliases->AddAlias("color", "contour.color", "ContourModel"); + } + Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h index d94c66219b..7bc0c17146 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h +++ b/Modules/ContourModel/Rendering/mitkContourModelMapper3D.h @@ -1,111 +1,111 @@ /*=================================================================== 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 _MITK_CONTOURMODEL_MAPPER_3D_H_ #define _MITK_CONTOURMODEL_MAPPER_3D_H_ #include "mitkCommon.h" #include #include "mitkBaseRenderer.h" #include "mitkVtkMapper.h" #include "mitkContourModel.h" //#include "mitkContourModelToVtkPolyDataFilter.h" #include #include #include #include #include -#include +#include namespace mitk { class MitkContourModel_EXPORT ContourModelMapper3D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro( ContourModelMapper3D,VtkMapper ); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) const mitk::ContourModel* GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); /*+++ methods of MITK-VTK rendering pipeline +++*/ virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); /*+++ END methods of MITK-VTK rendering pipeline +++*/ class MitkContourModel_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Actor of a 2D render window. */ vtkSmartPointer m_Actor; /** \brief Mapper of a 2D render window. */ vtkSmartPointer m_Mapper; - vtkSmartPointer m_TubeFilter; + vtkSmartPointer m_TubeFilter; //mitk::ContourModelToVtkPolyDataFilter::Pointer m_contourToPolyData; vtkSmartPointer m_OutlinePolyData; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage() { } }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: ContourModelMapper3D(); virtual ~ContourModelMapper3D(); void GenerateDataForRenderer( mitk::BaseRenderer *renderer ); virtual vtkSmartPointer CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour); virtual void ApplyContourProperties(mitk::BaseRenderer* renderer); }; } #endif diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp index 667410a59c..a29948904c 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelSetGLMapper2D.cpp @@ -1,383 +1,391 @@ /*=================================================================== 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 "mitkContourModelSetGLMapper2D.h" #include "mitkPlaneGeometry.h" #include "mitkColorProperty.h" #include "mitkProperties.h" #include "mitkContourModelSet.h" #include +#include +#include #include "mitkGL.h" mitk::ContourModelSetGLMapper2D::ContourModelSetGLMapper2D() { } mitk::ContourModelSetGLMapper2D::~ContourModelSetGLMapper2D() { } void mitk::ContourModelSetGLMapper2D::Paint(mitk::BaseRenderer * renderer) { BaseLocalStorage *ls = m_LSH.GetLocalStorage(renderer); mitk::DataNode* dataNode = this->GetDataNode(); bool visible = true; dataNode->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; mitk::ContourModelSet* input = this->GetInput(); mitk::ContourModelSet::ContourModelSetIterator it = input->Begin(); mitk::ContourModelSet::ContourModelSetIterator end = input->End(); while(it!=end) { this->DrawContour(it->GetPointer(), renderer); ++it; } if(input->GetSize() < 1) return; ls->UpdateGenerateDataTime(); } mitk::ContourModelSet* mitk::ContourModelSetGLMapper2D::GetInput(void) { return const_cast(static_cast ( GetDataNode()->GetData() )); } void mitk::ContourModelSetGLMapper2D::DrawContour(mitk::ContourModel* renderingContour, mitk::BaseRenderer* renderer) { if(!renderingContour) return; mitk::DataNode* dataNode = this->GetDataNode(); renderingContour->UpdateOutputInformation(); unsigned int timestep = renderer->GetTimeStep(); if ( !renderingContour->IsEmptyTimeStep(timestep) ) { mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); assert(displayGeometry.IsNotNull()); //apply color and opacity read from the PropertyList ApplyColorAndOpacityProperties(renderer); mitk::ColorProperty::Pointer colorprop = dynamic_cast(dataNode->GetProperty("contour.color", renderer)); float opacity = 0.5; dataNode->GetFloatProperty("opacity", opacity, renderer); if(colorprop) { //set the color of the contour double red = colorprop->GetColor().GetRed(); double green = colorprop->GetColor().GetGreen(); double blue = colorprop->GetColor().GetBlue(); glColor4f(red, green, blue, opacity); } mitk::ColorProperty::Pointer selectedcolor = dynamic_cast(dataNode->GetProperty("contour.points.color", renderer)); if(!selectedcolor) { selectedcolor = mitk::ColorProperty::New(1.0,0.0,0.1); } vtkLinearTransform* transform = dataNode->GetVtkTransform(); // ContourModel::OutputType point; mitk::Point3D point; mitk::Point3D p, projected_p; float vtkp[3]; float lineWidth = 3.0; bool drawit=false; bool isHovering = false; dataNode->GetBoolProperty("contour.hovering", isHovering); if (isHovering) dataNode->GetFloatProperty("contour.hovering.width", lineWidth); else dataNode->GetFloatProperty("contour.width", lineWidth); bool showSegments = false; dataNode->GetBoolProperty("contour.segments.show", showSegments); bool showControlPoints = false; dataNode->GetBoolProperty("contour.controlpoints.show", showControlPoints); bool showPoints = false; dataNode->GetBoolProperty("contour.points.show", showPoints); bool showPointsNumbers = false; dataNode->GetBoolProperty("contour.points.text", showPointsNumbers); bool showControlPointsNumbers = false; dataNode->GetBoolProperty("contour.controlpoints.text", showControlPointsNumbers); bool projectmode=false; dataNode->GetVisibility(projectmode, renderer, "contour.project-onto-plane"); mitk::ContourModel::VertexIterator pointsIt = renderingContour->IteratorBegin(timestep); Point2D pt2d; // projected_p in display coordinates Point2D lastPt2d; int index = 0; mitk::ScalarType maxDiff = 0.25; while ( pointsIt != renderingContour->IteratorEnd(timestep) ) { lastPt2d = pt2d; point = (*pointsIt)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //project to plane if(projectmode) { drawit=true; } else if(scalardiffIteratorBegin(timestep)) ) { glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(pt2d[0], pt2d[1]); glVertex2f(lastPt2d[0], lastPt2d[1]); glEnd(); glLineWidth(1); } } if (showControlPoints) { //draw ontrol points if ((*pointsIt)->IsControlPoint) { float pointsize = 4; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(selectedcolor->GetColor().GetRed(), selectedcolor->GetColor().GetBlue(), selectedcolor->GetColor().GetGreen()); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } } if (showPoints) { float pointsize = 3; Point2D tmp; Vector2D horz,vert; horz[1]=0; vert[0]=0; horz[0]=pointsize; vert[1]=pointsize; glColor3f(0.0, 0.0, 0.0); glLineWidth(1); //a rectangle around the point with the selected color glBegin (GL_LINE_LOOP); tmp=pt2d-horz; glVertex2dv(&tmp[0]); tmp=pt2d+vert; glVertex2dv(&tmp[0]); tmp=pt2d+horz; glVertex2dv(&tmp[0]); tmp=pt2d-vert; glVertex2dv(&tmp[0]); glEnd(); glLineWidth(1); //the actual point in the specified color to see the usual color of the point glColor3f(colorprop->GetColor().GetRed(),colorprop->GetColor().GetGreen(),colorprop->GetColor().GetBlue()); glPointSize(1); glBegin (GL_POINTS); tmp=pt2d; glVertex2dv(&tmp[0]); glEnd (); } if (showPointsNumbers) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0; OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); } if (showControlPointsNumbers && (*pointsIt)->IsControlPoint) { std::string l; std::stringstream ss; ss << index; l.append(ss.str()); mitk::VtkPropRenderer* OpenGLrenderer = dynamic_cast( renderer ); float rgb[3]; rgb[0] = 1.0; rgb[1] = 1.0; rgb[2] = 0.0; OpenGLrenderer->WriteSimpleText(l, pt2d[0] + 2, pt2d[1] + 2,rgb[0], rgb[1],rgb[2]); } index++; } pointsIt++; }//end while iterate over controlpoints //close contour if necessary if(renderingContour->IsClosed(timestep) && drawit && showSegments) { lastPt2d = pt2d; point = renderingContour->GetVertexAt(0,timestep)->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); glLineWidth(lineWidth); glBegin (GL_LINES); glVertex2f(lastPt2d[0], lastPt2d[1]); glVertex2f( pt2d[0], pt2d[1] ); glEnd(); glLineWidth(1); } //draw selected vertex if exists if(renderingContour->GetSelectedVertex()) { //transform selected vertex point = renderingContour->GetSelectedVertex()->Coordinates; itk2vtk(point, vtkp); transform->TransformPoint(vtkp, vtkp); vtk2itk(vtkp,p); displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); Vector3D diff=p-projected_p; ScalarType scalardiff = diff.GetNorm(); //---------------------------------- //draw point if close to plane if(scalardiffAddProperty( "contour.color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); + node->AddProperty( "color", ColorProperty::New(0.9, 1.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), renderer, overwrite ); node->AddProperty( "contour.points.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.segments.show", mitk::BoolProperty::New( true ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.show", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.width", mitk::FloatProperty::New( 1.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering.width", mitk::FloatProperty::New( 3.0 ), renderer, overwrite ); node->AddProperty( "contour.hovering", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.points.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.controlpoints.text", mitk::BoolProperty::New( false ), renderer, overwrite ); node->AddProperty( "contour.project-onto-plane", mitk::BoolProperty::New( false ), renderer, overwrite ); - node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); + IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); + + if(aliases != NULL) + { + aliases->AddAlias("color", "contour.color", "ContourModelSet"); + } + Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp index 5de27d6f60..feb26c2fbd 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp +++ b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.cpp @@ -1,206 +1,206 @@ /*=================================================================== 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 #include #include #include -#include "mitkSurface.h" +#include +#include +#include mitk::ContourModelSetMapper3D::ContourModelSetMapper3D() { } mitk::ContourModelSetMapper3D::~ContourModelSetMapper3D() { } const mitk::ContourModelSet* mitk::ContourModelSetMapper3D::GetInput( void ) { //convient way to get the data from the dataNode return static_cast< const mitk::ContourModelSet * >( GetDataNode()->GetData() ); } vtkProp* mitk::ContourModelSetMapper3D::GetVtkProp(mitk::BaseRenderer* renderer) { //return the actor corresponding to the renderer return m_LSH.GetLocalStorage(renderer)->m_Assembly; } void mitk::ContourModelSetMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { /* First convert the contourModel to vtkPolyData, then tube filter it and * set it input for our mapper */ LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); mitk::ContourModelSet* contourSet = static_cast< mitk::ContourModelSet* >( GetDataNode()->GetData() ); mitk::ContourModelSet::ContourModelSetIterator it = contourSet->Begin(); mitk::ContourModelSet::ContourModelSetIterator end = contourSet->End(); while(it!=end) { mitk::ContourModel* inputContour = it->GetPointer(); vtkSmartPointer polyData = this->CreateVtkPolyDataFromContour(inputContour, renderer); - vtkSmartPointer tubeFilter = vtkSmartPointer::New(); + vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetInputData(polyData); float lineWidth(1.0); if (this->GetDataNode()->GetFloatProperty( "contour.3D.width", lineWidth, renderer )) { - tubeFilter->SetRadius(lineWidth); + tubeFilter->SetWidth(lineWidth); }else { - tubeFilter->SetRadius(0.5); + tubeFilter->SetWidth(0.5); } - tubeFilter->CappingOn(); - tubeFilter->SetNumberOfSides(10); tubeFilter->Update(); vtkSmartPointer mapper = vtkSmartPointer::New(); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); mapper->SetInputConnection(tubeFilter->GetOutputPort()); //mapper->SetInput(polyData); localStorage->m_Assembly->AddPart(actor); ++it; } - this->ApplyContourProperties(renderer); + this->ApplyColorAndOpacityProperties(renderer); } void mitk::ContourModelSetMapper3D::Update(mitk::BaseRenderer* renderer) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); mitk::ContourModel* data = static_cast< mitk::ContourModel*>( GetDataNode()->GetData() ); if ( data == NULL ) { return; } // Calculate time step of the input data for the specified renderer (integer value) this->CalculateTimeStep( renderer ); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); if ( this->GetTimestep() == -1 ) { return; } const DataNode *node = this->GetDataNode(); data->UpdateOutputInformation(); //check if something important has changed and we need to rerender if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) { this->GenerateDataForRenderer( renderer ); } // since we have checked that nothing important has changed, we can set // m_LastUpdateTime to the current time localStorage->m_LastUpdateTime.Modified(); } vtkSmartPointer mitk::ContourModelSetMapper3D::CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour, mitk::BaseRenderer* renderer) { unsigned int timestep = this->GetTimestep(); LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); localStorage->m_contourToPolyData->SetInput(inputContour); localStorage->m_contourToPolyData->Update(); vtkSmartPointer polyData = vtkSmartPointer::New(); polyData = localStorage->m_contourToPolyData->GetOutput()->GetVtkPolyData(timestep); return polyData; } -void mitk::ContourModelSetMapper3D::ApplyContourProperties(mitk::BaseRenderer* renderer) +void mitk::ContourModelSetMapper3D::ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor*) { + MITK_INFO << "ApplyColorAndOpacityProperties()"; + LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + float color[3]; + this->GetDataNode()->GetColor(color, renderer); - mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty - ("contour.color", renderer)); - if(colorprop) + vtkSmartPointer collection = vtkSmartPointer::New(); + localStorage->m_Assembly->GetActors(collection); + collection->InitTraversal(); + for(vtkIdType i = 0; i < collection->GetNumberOfItems(); i++) { - //set the color of the contour - double red = colorprop->GetColor().GetRed(); - double green = colorprop->GetColor().GetGreen(); - double blue = colorprop->GetColor().GetBlue(); - - - vtkSmartPointer collection = vtkSmartPointer::New(); - localStorage->m_Assembly->GetActors(collection); - collection->InitTraversal(); - for(vtkIdType i = 0; i < collection->GetNumberOfItems(); i++) - { - vtkActor::SafeDownCast(collection->GetNextProp())->GetProperty()->SetColor(red, green, blue); - } + vtkActor::SafeDownCast(collection->GetNextProp())->GetProperty()->SetColor(color[0], color[1], color[2]); } } /*+++++++++++++++++++ LocalStorage part +++++++++++++++++++++++++*/ mitk::ContourModelSetMapper3D::LocalStorage* mitk::ContourModelSetMapper3D::GetLocalStorage(mitk::BaseRenderer* renderer) { return m_LSH.GetLocalStorage(renderer); } mitk::ContourModelSetMapper3D::LocalStorage::LocalStorage() { m_Assembly = vtkSmartPointer::New(); m_contourToPolyData = mitk::ContourModelToSurfaceFilter::New(); } void mitk::ContourModelSetMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { - node->AddProperty( "color", ColorProperty::New(1.0,0.0,0.0), renderer, overwrite ); + node->AddProperty( "color", ColorProperty::New(1.0,1.0,0.0), renderer, overwrite ); node->AddProperty( "contour.3D.width", mitk::FloatProperty::New( 0.5 ), renderer, overwrite ); + IPropertyAliases* aliases = CoreServices::GetPropertyAliases(); + + if (aliases != NULL) + { + aliases->AddAlias("color", "contour.color", "ContourModelSet"); + } + Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h index 74e01de925..247d99db8e 100644 --- a/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h +++ b/Modules/ContourModel/Rendering/mitkContourModelSetMapper3D.h @@ -1,107 +1,107 @@ /*=================================================================== 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 _MITK_CONTOURMODELSET_MAPPER_3D_H_ #define _MITK_CONTOURMODELSET_MAPPER_3D_H_ #include "mitkCommon.h" #include #include "mitkBaseRenderer.h" #include "mitkVtkMapper.h" #include "mitkContourModel.h" #include "mitkContourModelSet.h" #include "mitkContourModelToSurfaceFilter.h" #include #include #include #include #include #include -#include +#include namespace mitk { class MitkContourModel_EXPORT ContourModelSetMapper3D : public VtkMapper { public: /** Standard class typedefs. */ mitkClassMacro( ContourModelSetMapper3D,VtkMapper ); /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) const mitk::ContourModelSet* GetInput(void); /** \brief Checks whether this mapper needs to update itself and generate * data. */ virtual void Update(mitk::BaseRenderer * renderer); /*+++ methods of MITK-VTK rendering pipeline +++*/ virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); /*+++ END methods of MITK-VTK rendering pipeline +++*/ class MitkContourModel_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage { public: /** \brief Assembly of contours. */ vtkSmartPointer m_Assembly; mitk::ContourModelToSurfaceFilter::Pointer m_contourToPolyData; /** \brief Timestamp of last update of stored data. */ itk::TimeStamp m_LastUpdateTime; /** \brief Default constructor of the local storage. */ LocalStorage(); /** \brief Default deconstructor of the local storage. */ ~LocalStorage() { } }; /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ mitk::LocalStorageHandler m_LSH; /** \brief Get the LocalStorage corresponding to the current renderer. */ LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); /** \brief Set the default properties for general image rendering. */ static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); protected: ContourModelSetMapper3D(); virtual ~ContourModelSetMapper3D(); void GenerateDataForRenderer( mitk::BaseRenderer *renderer ); virtual vtkSmartPointer CreateVtkPolyDataFromContour(mitk::ContourModel* inputContour,mitk::BaseRenderer* renderer); - virtual void ApplyContourProperties(mitk::BaseRenderer* renderer); + virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL); }; } #endif diff --git a/Modules/DicomRT/CMakeLists.txt b/Modules/DicomRT/CMakeLists.txt new file mode 100644 index 0000000000..56e50c2ab7 --- /dev/null +++ b/Modules/DicomRT/CMakeLists.txt @@ -0,0 +1,12 @@ +# CREATE MODULE HERE +IF (NOT DEFINED DCMTK_dcmrt_LIBRARY OR DCMTK_dcmrt_LIBRARY) +MITK_CREATE_MODULE( + INCLUDE_DIRS DataStructures + DEPENDS MitkSegmentation MitkSceneSerializationBase + PACKAGE_DEPENDS DCMTK + QT_MODULE +) +ADD_SUBDIRECTORY(Testing) +ELSE() +MESSAGE("MITK DicomRT Support disabled because the DCMTK dcmrt library not found") +ENDIF() diff --git a/Modules/DicomRT/DataStructures/mitkDoseValueType.h b/Modules/DicomRT/DataStructures/mitkDoseValueType.h new file mode 100644 index 0000000000..ed3ba8680a --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkDoseValueType.h @@ -0,0 +1,37 @@ +/*=================================================================== + +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 _MITK_DOSE_VALUE_TYPE_H_ +#define _MITK_DOSE_VALUE_TYPE_H_ + +namespace mitk +{ + +/** + \brief Represents absolute dose values (in Gy). +*/ +typedef double DoseValueAbs; + +/** +\brief Represents relative dose values (in %). +*/ +typedef double DoseValueRel; + + +} // namespace mitk + +#endif //_MITK_DOSE_VALUE_TYPE_H_ diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp new file mode 100644 index 0000000000..fa4feb2218 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevel.cpp @@ -0,0 +1,79 @@ +/*=================================================================== + +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 "mitkIsoDoseLevel.h" + +mitk::IsoDoseLevel::IsoDoseLevel() : +m_DoseValue (0.0), + m_VisibleIsoLine ( true ), + m_VisibleColorWash (true) +{ + m_Color.Fill(0); +} + +mitk::IsoDoseLevel::IsoDoseLevel( const IsoDoseLevel & other ) +{ + if (&other != this) + { + this->m_Color = other.m_Color; + this->m_DoseValue = other.m_DoseValue; + this->m_VisibleColorWash = other.m_VisibleColorWash; + this->m_VisibleIsoLine = other.m_VisibleIsoLine; + } +} + +mitk::IsoDoseLevel::IsoDoseLevel(const DoseValueType & value, const ColorType& color, bool visibleIsoLine, bool visibleColorWash): + m_DoseValue (value), + m_Color (color), + m_VisibleIsoLine ( visibleIsoLine ), + m_VisibleColorWash ( visibleColorWash ) +{ +}; + +mitk::IsoDoseLevel::~IsoDoseLevel() +{ +} + +bool mitk::IsoDoseLevel::operator == ( const IsoDoseLevel& right) const +{ + bool result = this->m_DoseValue == right.m_DoseValue; + + result = result && (this->m_Color == right.m_Color); + result = result && (this->m_VisibleColorWash == right.m_VisibleColorWash); + result = result && (this->m_VisibleIsoLine == right.m_VisibleIsoLine); + + return result; +} + +bool mitk::IsoDoseLevel::operator <( const IsoDoseLevel& right) const +{ + return this->m_DoseValue < right.m_DoseValue; +} + +bool mitk::IsoDoseLevel::operator > ( const IsoDoseLevel& right) const +{ + return this->m_DoseValue > right.m_DoseValue; +} + +void mitk::IsoDoseLevel::PrintSelf(std::ostream &os, itk::Indent indent) const +{ + Superclass::PrintSelf(os,indent); + os< +#include +#include + +#include "mitkCommon.h" +#include "mitkDoseValueType.h" +#include "MitkDicomRTExports.h" + +namespace mitk +{ + + /** + \brief Stores values needed for the representation/visualization of dose iso levels. + * + * The dose iso level is defined in the topology of a dose distribution by the dose value + * that indicates the lower boundary of the iso level. The upper boundary is implicitly defined + * by the next IsoDoseLevel greater (higher dose value) than the current iso level. + * Color and the visibility options are used to indicate the visualization style. + */ + class MitkDicomRT_EXPORT IsoDoseLevel: public itk::Object + { + public: + typedef ::itk::RGBPixel ColorType; + typedef DoseValueRel DoseValueType; + + mitkClassMacro(IsoDoseLevel, itk::Object); + itkNewMacro(Self); + mitkNewMacro4Param(Self,DoseValueType, ColorType, bool, bool); + + /** Checks if current dose iso level instances is greater + according to the dose values.*/ + bool operator> ( const IsoDoseLevel& right ) const; + /** Checks if current dose iso level instances is lesser + according to the dose values.*/ + bool operator< ( const IsoDoseLevel& right ) const; + + bool operator == ( const IsoDoseLevel& right) const; + + itkSetMacro(DoseValue,DoseValueType); + itkGetConstMacro(DoseValue,DoseValueType); + + itkSetMacro(Color,ColorType); + itkGetConstMacro(Color,ColorType); + + itkSetMacro(VisibleIsoLine,bool); + itkGetConstMacro(VisibleIsoLine,bool); + itkBooleanMacro(VisibleIsoLine); + + itkSetMacro(VisibleColorWash,bool); + itkGetConstMacro(VisibleColorWash,bool); + itkBooleanMacro(VisibleColorWash); + + protected: + IsoDoseLevel(); + IsoDoseLevel(const IsoDoseLevel & other); + IsoDoseLevel(const DoseValueType & value, const ColorType& color, bool visibleIsoLine = true, bool visibleColorWash = true ); + virtual ~IsoDoseLevel(); + + mitkCloneMacro(IsoDoseLevel); + + void PrintSelf(std::ostream &os, itk::Indent indent) const; + + private: + /** Relative dose value and lower boundary of the iso level instance + */ + DoseValueType m_DoseValue; + + /** RGB color code that should be used for the iso level.*/ + ColorType m_Color; + + /** indicates if an iso line should be shown for the iso level + (the lower boundary indicated by m_DoseValue)*/ + bool m_VisibleIsoLine; + + /** indicates if a color wash should be shown for the iso level.*/ + bool m_VisibleColorWash; + + /** Not implemented on purpose*/ + IsoDoseLevel& operator = (const IsoDoseLevel& source); + }; + +} // namespace mitk + +#endif //_MITK_DOSE_ISO_LEVEL_H_ diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp new file mode 100644 index 0000000000..f39b3a264e --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.cpp @@ -0,0 +1,148 @@ +/*=================================================================== + +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 + +#include "mitkIsoDoseLevelCollections.h" +#include "mitkExceptionMacro.h" + +namespace mitk +{ + namespace rt + { + /** "Private" functor used in std::find_if to find IsoDoseLevels with a given reference value */ + class EqualDoseFunctor + { + public: + typedef IsoDoseLevel::DoseValueType DoseValueType; + + EqualDoseFunctor(const DoseValueType& refValue) : m_refValue(refValue) + {}; + + bool operator () (const IsoDoseLevel* level) + { + return level->GetDoseValue() == m_refValue; + } + + protected: + DoseValueType m_refValue; + }; + + /** "Private" binary function used in std::sort to check the order of IsoDoseLeveles */ + bool lesserIsoDoseLevel(const IsoDoseLevel* first, const IsoDoseLevel* second) + { + return first->GetDoseValue() < second->GetDoseValue(); + } + } +} + +mitk::IsoDoseLevelSet::IsoDoseLevelSet(const IsoDoseLevelSet & other) +{ + if (&other != this) + { + this->m_IsoLevels = other.m_IsoLevels; + } +}; + +const mitk::IsoDoseLevel& mitk::IsoDoseLevelSet::GetIsoDoseLevel(IsoLevelIndexType index) const +{ + if (index < this->m_IsoLevels.size()) + { + return *(this->m_IsoLevels[index].GetPointer()); + } + else + { + mitkThrow() << "Try to access non existing dose iso level."; + } +}; + +const mitk::IsoDoseLevel& mitk::IsoDoseLevelSet::GetIsoDoseLevel(DoseValueType value) const +{ + InternalVectorType::const_iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), rt::EqualDoseFunctor(value)); + + if (pos != this->m_IsoLevels.end()) + { + return *(pos->GetPointer()); + } + else + { + mitkThrow() << "Try to access non existing dose iso level."; + } +}; + +void mitk::IsoDoseLevelSet::SetIsoDoseLevel(const IsoDoseLevel* level) +{ + if (!level) + { + mitkThrow() << "Cannot set iso level. Passed null pointer."; + } + + this->DeleteIsoDoseLevel(level->GetDoseValue()); + + this->m_IsoLevels.push_back(level->Clone()); + + std::sort(this->m_IsoLevels.begin(), this->m_IsoLevels.end(),rt::lesserIsoDoseLevel); +}; + +bool mitk::IsoDoseLevelSet::DoseLevelExists(IsoLevelIndexType index) const +{ + return index < this->m_IsoLevels.size(); +}; + + +bool mitk::IsoDoseLevelSet::DoseLevelExists(DoseValueType value) const +{ + InternalVectorType::const_iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), rt::EqualDoseFunctor(value)); + return pos != this->m_IsoLevels.end(); +}; + +void mitk::IsoDoseLevelSet::DeleteIsoDoseLevel(DoseValueType value) +{ + InternalVectorType::iterator pos = std::find_if(this->m_IsoLevels.begin(), this->m_IsoLevels.end(), rt::EqualDoseFunctor(value)); + + if (pos != this->m_IsoLevels.end()) + { + this->m_IsoLevels.erase(pos); + } +}; + +void mitk::IsoDoseLevelSet::DeleteIsoDoseLevel(IsoLevelIndexType index) +{ + if (DoseLevelExists(index)) + { + this->m_IsoLevels.erase(this->m_IsoLevels.begin()+index); + } +}; + +mitk::IsoDoseLevelSet::ConstIterator mitk::IsoDoseLevelSet::Begin(void) const +{ + return ConstIterator(this->m_IsoLevels.begin()); +}; + +mitk::IsoDoseLevelSet::ConstIterator mitk::IsoDoseLevelSet::End(void) const +{ + return ConstIterator(this->m_IsoLevels.end()); +}; + +mitk::IsoDoseLevelSet::IsoLevelIndexType mitk::IsoDoseLevelSet::Size(void) const +{ + return this->m_IsoLevels.size(); +}; + +void mitk::IsoDoseLevelSet::Reset(void) +{ + this->m_IsoLevels.clear(); +}; diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h new file mode 100644 index 0000000000..9f674d59ed --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelCollections.h @@ -0,0 +1,161 @@ +/*=================================================================== + +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 _MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_ +#define _MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_ + +#include +#include + +#include "mitkIsoDoseLevel.h" + +namespace mitk +{ + + + /** + \class IsoDoseLevelVector + \brief Simple vector that stores dose iso levels. + * + * This class is for example used to store the user defined free iso values. + */ + typedef ::itk::VectorContainer IsoDoseLevelVector; + + + /** + \class IsoDoseLevelSet + \brief Stores values needed for the representation/visualization of dose iso levels. + * + * Set of dose iso levels sorted by the dose values of the iso levels (low to high values). + * This data structure is used to represent the dose iso level setup used for the + * visualization of a dose distribution. + */ +class MitkDicomRT_EXPORT IsoDoseLevelSet: + public itk::Object +{ +public: + mitkClassMacro(IsoDoseLevelSet, itk::Object); + itkNewMacro(Self); + +private: + /** Quick access to the STL vector type that was inherited. */ + typedef std::vector< IsoDoseLevel::Pointer > InternalVectorType; + typedef InternalVectorType::size_type size_type; + typedef InternalVectorType::iterator VectorIterator; + typedef InternalVectorType::const_iterator VectorConstIterator; + + InternalVectorType m_IsoLevels; + +protected: + IsoDoseLevelSet() {}; + IsoDoseLevelSet(const IsoDoseLevelSet & other); + + virtual ~IsoDoseLevelSet() {}; + + mitkCloneMacro(IsoDoseLevelSet); + +public: + typedef size_type IsoLevelIndexType; + typedef IsoDoseLevel::DoseValueType DoseValueType; + + /** Convenient typedefs for the iterator and const iterator. */ + class ConstIterator; + + /** Friends to this class. */ + friend class ConstIterator; + + /** \class ConstIterator + * Simulate STL-vector style const iteration where dereferencing the iterator + * gives read access to the value. + */ + class ConstIterator + { +public: + ConstIterator() {} + ConstIterator(const VectorConstIterator & i): m_Iter(i) {} + ConstIterator(const ConstIterator & r) { m_Iter = r.m_Iter; } + const IsoDoseLevel & operator*() { return *(m_Iter->GetPointer()); } + const IsoDoseLevel * operator->() { return m_Iter->GetPointer(); } + ConstIterator & operator++() {++m_Iter; return *this; } + ConstIterator operator++(int) { ConstIterator temp(*this); ++m_Iter; return temp; } + ConstIterator & operator--() {--m_Iter; return *this; } + ConstIterator operator--(int) { ConstIterator temp(*this); --m_Iter; return temp; } + ConstIterator & operator=(const ConstIterator & r) {m_Iter = r.m_Iter; return *this; } + bool operator==(const ConstIterator & r) const { return m_Iter == r.m_Iter; } + bool operator!=(const ConstIterator & r) const { return m_Iter != r.m_Iter; } + + const IsoDoseLevel & Value(void) const { return *(m_Iter->GetPointer()); } + +private: + VectorConstIterator m_Iter; + }; + + /* Declare the public interface routines. */ + + /** + * Read the element from the given index. + * It is assumed that the index exists. + */ + const IsoDoseLevel& GetIsoDoseLevel(IsoLevelIndexType) const; + const IsoDoseLevel& GetIsoDoseLevel(DoseValueType) const; + + /** + * Set the element value at the given index. + * It is assumed that the index exists. + */ + void SetIsoDoseLevel(const IsoDoseLevel*); + + /** + * Check if the index range of the vector is large enough to allow the + * given index without expansion. + */ + bool DoseLevelExists(IsoLevelIndexType) const; + bool DoseLevelExists(DoseValueType) const; + + /** + * Delete the element defined by the index identifier. In practice, it + * doesn't make sense to delete a vector index. Instead, this method just + * overwrites the index with the default element. + */ + void DeleteIsoDoseLevel(DoseValueType); + void DeleteIsoDoseLevel(IsoLevelIndexType); + + /** + * Get a begin const iterator for the vector. + */ + ConstIterator Begin(void) const; + + /** + * Get an end const iterator for the vector. + */ + ConstIterator End(void) const; + + /** + * Get the number of elements currently stored in the vector. + */ + IsoLevelIndexType Size(void) const; + + /** + * Clear the elements. The final size will be zero. + */ + void Reset(void); +}; + + +} + +#endif //_MITK_DOSE_ISO_LEVEL_COLLECTIONS_H_ diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp new file mode 100644 index 0000000000..8d15835b82 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.cpp @@ -0,0 +1,107 @@ +/*=================================================================== + +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 "mitkIsoDoseLevelSetProperty.h" + + +mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty() +{ +} + +mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(const mitk::IsoDoseLevelSetProperty& other) + : BaseProperty(other) + , m_IsoLevelSet(other.m_IsoLevelSet) +{ +} + +mitk::IsoDoseLevelSetProperty::IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet) : m_IsoLevelSet(levelSet) +{ +} + +mitk::IsoDoseLevelSetProperty::~IsoDoseLevelSetProperty() +{ +} + +bool mitk::IsoDoseLevelSetProperty::IsEqual(const BaseProperty& property) const +{ + return this->m_IsoLevelSet == static_cast(property).m_IsoLevelSet; +} + +bool mitk::IsoDoseLevelSetProperty::Assign(const BaseProperty& property) +{ + this->m_IsoLevelSet = static_cast(property).m_IsoLevelSet; + return true; +} + +const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet() const +{ + return m_IsoLevelSet; +} + +const mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue() const +{ + return GetIsoDoseLevelSet(); +} + +mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetIsoDoseLevelSet() +{ + return m_IsoLevelSet; +} + +mitk::IsoDoseLevelSet * mitk::IsoDoseLevelSetProperty::GetValue() +{ + return GetIsoDoseLevelSet(); +} + + +void mitk::IsoDoseLevelSetProperty::SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet) +{ + if(m_IsoLevelSet != levelSet) + { + m_IsoLevelSet = levelSet; + Modified(); + } +} + +void mitk::IsoDoseLevelSetProperty::SetValue(IsoDoseLevelSet* levelSet) +{ + SetIsoDoseLevelSet(levelSet); +} + +std::string mitk::IsoDoseLevelSetProperty::GetValueAsString() const +{ + std::stringstream myStr; + + myStr << "IsoDoseLevels: "; + + if (m_IsoLevelSet.IsNotNull()) + { + myStr << m_IsoLevelSet->Size() << std::endl; + + for (IsoDoseLevelSet::ConstIterator pos = m_IsoLevelSet->Begin(); pos != m_IsoLevelSet->End(); ++pos) + { + myStr << " " << 100*(pos->GetDoseValue()) << "% : ("<GetColor()<< "); iso line: " << pos->GetVisibleIsoLine() << "; color wash: "<GetVisibleColorWash() << std::endl; + } + } + return myStr.str(); +} + +itk::LightObject::Pointer mitk::IsoDoseLevelSetProperty::InternalClone() const +{ + itk::LightObject::Pointer result(new Self(*this)); + return result; +} diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h new file mode 100644 index 0000000000..9f95ee3fb6 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelSetProperty.h @@ -0,0 +1,82 @@ +/*=================================================================== + +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 _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ +#define _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ + +#include "mitkBaseProperty.h" +#include "mitkIsoDoseLevelCollections.h" +#include "MitkDicomRTExports.h" + +namespace mitk { + + +/** +\brief Property class for dose iso level sets. +*/ +class MitkDicomRT_EXPORT IsoDoseLevelSetProperty : public BaseProperty +{ + +protected: + IsoDoseLevelSet::Pointer m_IsoLevelSet; + + IsoDoseLevelSetProperty(); + + IsoDoseLevelSetProperty(const IsoDoseLevelSetProperty& other); + + IsoDoseLevelSetProperty(IsoDoseLevelSet* levelSet); + +public: + mitkClassMacro(IsoDoseLevelSetProperty, BaseProperty); + + itkNewMacro(IsoDoseLevelSetProperty); + mitkNewMacro1Param(IsoDoseLevelSetProperty, IsoDoseLevelSet*); + + typedef IsoDoseLevelSet ValueType; + + virtual ~IsoDoseLevelSetProperty(); + + const IsoDoseLevelSet * GetIsoDoseLevelSet() const; + const IsoDoseLevelSet * GetValue() const; + IsoDoseLevelSet * GetIsoDoseLevelSet(); + IsoDoseLevelSet * GetValue(); + + + void SetIsoDoseLevelSet(IsoDoseLevelSet* levelSet); + void SetValue(IsoDoseLevelSet* levelSet); + + virtual std::string GetValueAsString() const; + + using BaseProperty::operator=; + +private: + + // purposely not implemented + IsoDoseLevelSetProperty& operator=(const IsoDoseLevelSetProperty&); + + itk::LightObject::Pointer InternalClone() const; + + virtual bool IsEqual(const BaseProperty& property) const; + virtual bool Assign(const BaseProperty& property); + +}; + +} // namespace mitk + + + +#endif /* _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ */ diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp new file mode 100644 index 0000000000..cc4b577bc7 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.cpp @@ -0,0 +1,107 @@ +/*=================================================================== + +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 "mitkIsoDoseLevelVectorProperty.h" + + +mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty() +{ +} + +mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(const mitk::IsoDoseLevelVectorProperty& other) + : BaseProperty(other) + , m_IsoLevelVector(other.m_IsoLevelVector) +{ +} + +mitk::IsoDoseLevelVectorProperty::IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector) : m_IsoLevelVector(levelVector) +{ +} + +mitk::IsoDoseLevelVectorProperty::~IsoDoseLevelVectorProperty() +{ +} + +bool mitk::IsoDoseLevelVectorProperty::IsEqual(const BaseProperty& property) const +{ + return this->m_IsoLevelVector == static_cast(property).m_IsoLevelVector; +} + +bool mitk::IsoDoseLevelVectorProperty::Assign(const BaseProperty& property) +{ + this->m_IsoLevelVector = static_cast(property).m_IsoLevelVector; + return true; +} + +const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector() const +{ + return m_IsoLevelVector; +} + +const mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue() const +{ + return GetIsoDoseLevelVector(); +} + +mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetIsoDoseLevelVector() +{ + return m_IsoLevelVector; +} + +mitk::IsoDoseLevelVector * mitk::IsoDoseLevelVectorProperty::GetValue() +{ + return GetIsoDoseLevelVector(); +} + + +void mitk::IsoDoseLevelVectorProperty::SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector) +{ + if(m_IsoLevelVector != levelVector) + { + m_IsoLevelVector = levelVector; + Modified(); + } +} + +void mitk::IsoDoseLevelVectorProperty::SetValue(IsoDoseLevelVector* levelVector) +{ + SetIsoDoseLevelVector(levelVector); +} + +std::string mitk::IsoDoseLevelVectorProperty::GetValueAsString() const +{ + std::stringstream myStr; + + myStr << "IsoDoseLevels: "; + + if (m_IsoLevelVector.IsNotNull()) + { + myStr << m_IsoLevelVector->Size() << std::endl; + + for (IsoDoseLevelVector::ConstIterator pos = m_IsoLevelVector->Begin(); pos != m_IsoLevelVector->End(); ++pos) + { + myStr << " " << 100*(pos->Value()->GetDoseValue()) << "% : ("<Value()->GetColor()<< "); iso line: " << pos->Value()->GetVisibleIsoLine() << std::endl; + } + } + return myStr.str(); +} + +itk::LightObject::Pointer mitk::IsoDoseLevelVectorProperty::InternalClone() const +{ + itk::LightObject::Pointer result(new Self(*this)); + return result; +} diff --git a/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h new file mode 100644 index 0000000000..cd2921e877 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkIsoDoseLevelVectorProperty.h @@ -0,0 +1,82 @@ +/*=================================================================== + +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 _MITK_DOSE_ISO_LEVEL_VECTOR_PROPERTY_H_ +#define _MITK_DOSE_ISO_LEVEL_VECTOR_PROPERTY_H_ + +#include "mitkBaseProperty.h" +#include "mitkIsoDoseLevelCollections.h" +#include "MitkDicomRTExports.h" + +namespace mitk { + + +/** +\brief Property class for dose iso level vector. +*/ +class MitkDicomRT_EXPORT IsoDoseLevelVectorProperty : public BaseProperty +{ + +protected: + IsoDoseLevelVector::Pointer m_IsoLevelVector; + + IsoDoseLevelVectorProperty(); + + IsoDoseLevelVectorProperty(const IsoDoseLevelVectorProperty& other); + + IsoDoseLevelVectorProperty(IsoDoseLevelVector* levelVector); + +public: + mitkClassMacro(IsoDoseLevelVectorProperty, BaseProperty); + + itkNewMacro(IsoDoseLevelVectorProperty); + mitkNewMacro1Param(IsoDoseLevelVectorProperty, IsoDoseLevelVector*); + + typedef IsoDoseLevelVector ValueType; + + virtual ~IsoDoseLevelVectorProperty(); + + const IsoDoseLevelVector * GetIsoDoseLevelVector() const; + const IsoDoseLevelVector * GetValue() const; + IsoDoseLevelVector * GetIsoDoseLevelVector(); + IsoDoseLevelVector * GetValue(); + + + void SetIsoDoseLevelVector(IsoDoseLevelVector* levelVector); + void SetValue(IsoDoseLevelVector* levelVector); + + virtual std::string GetValueAsString() const; + + using BaseProperty::operator=; + +private: + + // purposely not implemented + IsoDoseLevelVectorProperty& operator=(const IsoDoseLevelVectorProperty&); + + itk::LightObject::Pointer InternalClone() const; + + virtual bool IsEqual(const BaseProperty& property) const; + virtual bool Assign(const BaseProperty& property); + +}; + +} // namespace mitk + + + +#endif /* _MITK_DOSE_ISO_LEVEL_SET_PROPERTY_H_ */ diff --git a/Modules/DicomRT/DataStructures/mitkRTConstants.cpp b/Modules/DicomRT/DataStructures/mitkRTConstants.cpp new file mode 100644 index 0000000000..a54dae2331 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkRTConstants.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +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 "mitkRTConstants.h" + +const std::string mitk::rt::Constants::DOSE_PROPERTY_NAME = "dose"; +const std::string mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME = "dose.PrescribedDose"; +const std::string mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME = "dose.ReferenceDose"; +const std::string mitk::rt::Constants::DOSE_TYPE_PROPERTY_NAME = "dose.type"; +const std::string mitk::rt::Constants::DOSE_SUMMATION_TYPE_PROPERTY_NAME = "dose.summationType"; +const std::string mitk::rt::Constants::DOSE_FRACTION_COUNT_PROPERTY_NAME = "dose.fractionCount"; +const std::string mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME = "dose.showIsoLines"; +const std::string mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME = "dose.showColorWash"; +const std::string mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME = "dose.isoLevels"; +const std::string mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME = "dose.freeIsoValues"; diff --git a/Modules/DicomRT/DataStructures/mitkRTConstants.h b/Modules/DicomRT/DataStructures/mitkRTConstants.h new file mode 100644 index 0000000000..69d8783905 --- /dev/null +++ b/Modules/DicomRT/DataStructures/mitkRTConstants.h @@ -0,0 +1,90 @@ +/*=================================================================== + +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 _MITK_RT_CONSTANTS_H_ +#define _MITK_RT_CONSTANTS_H_ + +#include + +#include "MitkDicomRTExports.h" + +namespace mitk +{ + namespace rt + { + struct MitkDicomRT_EXPORT Constants + { + /** + * Name of the property that indicates if a data/node is a dose. + */ + static const std::string DOSE_PROPERTY_NAME; + + /** + * Name of the property that encodes the prescribed dose associated with the data node + * If a RTPLAN file exists the value can be extracted from the tag (300A,0026) - Target Prescription Dose in the plan file. + */ + static const std::string PRESCRIBED_DOSE_PROPERTY_NAME; + + /** + * Name of the property that encodes the reference dose that should be used for relative dose vizualization/evaluation purpose. + * It is often the prescribed dose but may differ e.g. when to dose distributions sould be compared using the same reference. + */ + static const std::string REFERENCE_DOSE_PROPERTY_NAME; + + /** + * Name of the property that encodes the optional string property holding the information from the tag (3004,0004) - Dose Type. + * This contains useful information for medical doctors + */ + static const std::string DOSE_TYPE_PROPERTY_NAME; + + /** + * Name of the property that encodes the optional string property holding the information from the tag (3004,000A) - Dose Summation Type. + * This contains useful information for medical doctors + */ + static const std::string DOSE_SUMMATION_TYPE_PROPERTY_NAME; + + /** + * Name of the property that encodes the number of fractions. + * It is for example in DICOM stored in tag (300A,0078) - Number of Fractions Prescribed (from the RTPLAN file if this file exists). + * This value could be used to further scale the dose according to dose summation type. + * For example a given plan consists of 8 fractions. Scaling the fraction dose by 8 gives the complete planned dose. + */ + static const std::string DOSE_FRACTION_COUNT_PROPERTY_NAME; + + /** + * Name of the property that encodes if the iso line rendering should be activated for the node. + */ + static const std::string DOSE_SHOW_ISOLINES_PROPERTY_NAME; + + /** + * Name of the property that encodes if the color wash rendering should be activated for the node. + */ + static const std::string DOSE_SHOW_COLORWASH_PROPERTY_NAME; + + /** + * Name of the property that encodes if the set of iso levels should be used to visualize the dose distribution. + */ + static const std::string DOSE_ISO_LEVELS_PROPERTY_NAME; + + /** + * Name of the property that encodes user defined iso values that mark special dose values in the distribution. + */ + static const std::string DOSE_FREE_ISO_VALUES_PROPERTY_NAME; + }; + } +} + +#endif diff --git a/Modules/DicomRT/Testing/CMakeLists.txt b/Modules/DicomRT/Testing/CMakeLists.txt new file mode 100644 index 0000000000..153cd81e2e --- /dev/null +++ b/Modules/DicomRT/Testing/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() diff --git a/Modules/DicomRT/Testing/files.cmake b/Modules/DicomRT/Testing/files.cmake new file mode 100644 index 0000000000..744a5ab21b --- /dev/null +++ b/Modules/DicomRT/Testing/files.cmake @@ -0,0 +1,3 @@ +SET(MODULE_TESTS + mitkDicomRTReaderTest.cpp +) diff --git a/Modules/DicomRT/Testing/mitkDicomRTReaderTest.cpp b/Modules/DicomRT/Testing/mitkDicomRTReaderTest.cpp new file mode 100644 index 0000000000..7e2a2df857 --- /dev/null +++ b/Modules/DicomRT/Testing/mitkDicomRTReaderTest.cpp @@ -0,0 +1,114 @@ +/*=================================================================== + +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 "mitkTestingMacros.h" +#include "mitkDicomRTReader.h" +#include + + +int mitkDicomRTReaderTest(int argc , char* argv[]) +{ + // always start with this! + MITK_TEST_BEGIN("DicomRTReader") + + mitk::DicomRTReader::Pointer _DicomRTReader = mitk::DicomRTReader::New(); + + char* h = "/home/riecker/DicomRT/DICOMRT_Bilder/DICOM-RT/W_K/RD1.2.826.0.1.3680043.8.176.2013826103830726.377.2260480657.dcm"; + char* i = "/home/riecker/DicomRT/DICOMRT_Bilder/RD.1.2.246.352.71.7.2088656855.452083.20110920153746.dcm"; + char* j = "/home/riecker/DicomRT/DICOMRT_Bilder/2/RTDOSE.2.16.840.1.113669.2.931128.509887832.20120106104806.483734.dcm"; + + mitk::ContourModelSet::Pointer emptyItem; + std::deque result; + result = _DicomRTReader->ReadDicomFile(h); + +// DcmFileFormat file; +// OFCondition outp = file.loadFile(argv[1], EXS_Unknown); +// DcmDataset *dataset = file.getDataset(); + +// std::cout << "Filename:" << argv[1] << "\n\n"; + +// int x = _DicomRTReader->LoadRTDose(dataset); + +// ContourModelVector result = _DicomRTReader->ReadStructureSet(dataset); + + +// mitk::ContourModel::Pointer real = mitk::ContourModel::New(); +// real = result.front(); + +// mitk::Point3D point; +// point[0] = 30.9; +// point[1] = 20.6; +// point[2] = 11.7; + +// mitk::Point3D samePoint; +// samePoint[0] = -0.3823089599609; +// samePoint[1] = -0.3836975097656; +// samePoint[2] = 2.5; + +// mitk::Point3D b; +// b[0] = -0.3823089599609; +// b[1] = -0.3836975097656; +// b[2] = 2.5; + +// mitk::ContourModel::Pointer created = mitk::ContourModel::New(); +// created->AddVertex(point); +// created->Close(); + +// mitk::ContourModel::Pointer same = mitk::ContourModel::New(); +// same->AddVertex(samePoint); +// same->Close(); + +// mitk::ContourModel::Pointer a1 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer a2 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer a3 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer a4 = mitk::ContourModel::New(); + +// mitk::ContourModel::Pointer a5 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer a6 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer a7 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer empty0 = mitk::ContourModel::New(); +// mitk::ContourModel::Pointer empty1 = mitk::ContourModel::New(); + +// a1->AddVertex(samePoint); +// a2->AddVertex(samePoint); +// a3->AddVertex(b); +// a4->AddVertex(point); + +// a5->AddVertex(samePoint); +// a5->AddVertex(b); +// a6->AddVertex(b); +// a6->AddVertex(samePoint); +// a7->AddVertex(samePoint); +// a7->AddVertex(point); + +// MITK_TEST_CONDITION_REQUIRED( !real->IsEmpty() , " 01. Tests if the first ContouModelObject from ReadDicomFile/Struct isnt empty -> False" ); +// MITK_TEST_CONDITION_REQUIRED( real != created , " 02. Tests if created ContourModel is different to frist ContourModel -> True" ); +// MITK_TEST_CONDITION_REQUIRED( same != real , " 03. Tests if the ContourModel looks like in the DcmDump Output -> True" ); +// MITK_TEST_CONDITION_REQUIRED( samePoint == b , " 04. Tests the two Points with same coords -> True" ); + +// MITK_TEST_CONDITION_REQUIRED( _DicomRTReader->Equals(empty0,empty1) , " 05. Tests two empty ContourModels -> True" ); +// MITK_TEST_CONDITION_REQUIRED( !_DicomRTReader->Equals(a1,empty0) , " 06. Tests Model with 1 Point and empty Model -> False" ); +// MITK_TEST_CONDITION_REQUIRED( !_DicomRTReader->Equals(a1,a4) , " 07. Tests Models with 1 different point -> False" ); +// MITK_TEST_CONDITION_REQUIRED( _DicomRTReader->Equals(a1,a3) , " 08. Tests Models with 1 point and same coords -> True" ); +// MITK_TEST_CONDITION_REQUIRED( !_DicomRTReader->Equals(a5,a1) , " 09. Tests a Model with 2 points and a model with one point, first point is the same -> False" ); +// MITK_TEST_CONDITION_REQUIRED( !_DicomRTReader->Equals(a5,a4) , " 10. Tests a Model with 2 points and a model with one point, first point is different -> False" ); +// MITK_TEST_CONDITION_REQUIRED( _DicomRTReader->Equals(a5,a6) , " 11. Tests two Models with 2 points and same coords -> True" ); +// MITK_TEST_CONDITION_REQUIRED( !_DicomRTReader->Equals(a5,a7) , " 12. Tests two Models with 2 points first is the same second is different -> False" ); + +// std::cout << "\n"; + // always end with this! + MITK_TEST_END() +} diff --git a/Modules/DicomRT/files.cmake b/Modules/DicomRT/files.cmake new file mode 100644 index 0000000000..b209527aca --- /dev/null +++ b/Modules/DicomRT/files.cmake @@ -0,0 +1,24 @@ +SET(CPP_FILES + mitkDicomRTReader.cpp + DataStructures/mitkRTConstants.cpp + DataStructures/mitkIsoDoseLevel.cpp + DataStructures/mitkIsoDoseLevelCollections.cpp + DataStructures/mitkIsoDoseLevelSetProperty.cpp + DataStructures/mitkIsoDoseLevelVectorProperty.cpp +) + +set(H_FILES + mitkDicomRTReader.h + DataStructures/mitkIsoDoseLevel.h + DataStructures/mitkIsoDoseLevelCollections.h + DataStructures/mitkIsoDoseLevelSetProperty.h + DataStructures/mitkIsoDoseLevelVectorProperty.h + DataStructures/mitkDoseValueType.h + DataStructures/mitkRTConstants.h +) + +set(TPP_FILES +) + +set(MOC_H_FILES +) diff --git a/Modules/DicomRT/mitkDicomRTReader.cpp b/Modules/DicomRT/mitkDicomRTReader.cpp new file mode 100644 index 0000000000..3190d0268f --- /dev/null +++ b/Modules/DicomRT/mitkDicomRTReader.cpp @@ -0,0 +1,426 @@ +/*=================================================================== + +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 "mitkDicomRTReader.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mitk +{ + + DicomRTReader::DicomRTReader(){} + + DicomRTReader::~DicomRTReader(){} + + DicomRTReader::RoiEntry::RoiEntry() + { + Number=0; + DisplayColor[0]=1.0; + DisplayColor[1]=0.0; + DisplayColor[2]=0.0; + ContourModelSet=mitk::ContourModelSet::New(); + } + + DicomRTReader::RoiEntry::~RoiEntry(){} + + DicomRTReader::RoiEntry::RoiEntry(const RoiEntry& src) + { + Number=src.Number; + Name=src.Name; + Description=src.Description; + DisplayColor[0]=src.DisplayColor[0]; + DisplayColor[1]=src.DisplayColor[1]; + DisplayColor[2]=src.DisplayColor[2]; + ContourModelSet=mitk::ContourModelSet::New(); + SetPolyData(src.ContourModelSet); + } + + DicomRTReader::RoiEntry& DicomRTReader::RoiEntry:: + operator=(const RoiEntry &src) + { + Number=src.Number; + Name=src.Name; + Description=src.Description; + DisplayColor[0]=src.DisplayColor[0]; + DisplayColor[1]=src.DisplayColor[1]; + DisplayColor[2]=src.DisplayColor[2]; + SetPolyData(src.ContourModelSet); + return (*this); + } + + void DicomRTReader::RoiEntry:: + SetPolyData(mitk::ContourModelSet::Pointer roiPolyData) + { + if (roiPolyData == this->ContourModelSet) + return; + this->ContourModelSet = roiPolyData; + } + + std::deque DicomRTReader:: + ReadDicomFile(char* filename) + { + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.good()) + { + DcmDataset *dataset = file.getDataset(); + OFString sopClass; + if(dataset->findAndGetOFString + (DCM_SOPClassUID, sopClass).good() && !sopClass.empty()) + { + if(sopClass == UID_RTDoseStorage) + { + mitk::DataNode::Pointer x = mitk::DataNode::New(); + x = this->DicomRTReader::LoadRTDose(dataset, filename); + ContourModelSetVector y; + return y; + } + else if(sopClass == UID_RTStructureSetStorage) + { + ContourModelSetVector x = + this->DicomRTReader::ReadStructureSet(dataset); + return x; + } + else + { + MITK_ERROR << "Error matching SOP Class, maybe an unsupported type" + << endl; + ContourModelSetVector y; + return y; + } + } + else + { + MITK_ERROR << "Error reading the SOPClassID" << endl; + ContourModelSetVector y; + return y; + } + } + else + { + MITK_ERROR << "Error rading the input file" << endl; + ContourModelSetVector y; + return y; + } + } + + size_t DicomRTReader::GetNumberOfRois() + { + return this->RoiSequenceVector.size(); + } + + DicomRTReader::RoiEntry* DicomRTReader::FindRoiByNumber(unsigned int roiNum) + { + for(unsigned int i=0; iRoiSequenceVector.size(); ++i) + { + if(this->RoiSequenceVector[i].Number == roiNum) + return &this->RoiSequenceVector[i]; + } + return NULL; + } + + std::deque DicomRTReader:: + ReadStructureSet(DcmDataset* dataset) + { + /** + * @brief For storing contourmodelsets that belongs to the same object + * + * e.g. An eye consists of several contourmodels (contourmodel consists + * of several 3D-Points) and together they are a contourmodelset + */ + ContourModelSetVector contourModelSetVector; + + DRTStructureSetIOD structureSetObject; + OFCondition outp = structureSetObject.read(*dataset); + if(!outp.good()) + { + MITK_ERROR << "Error reading the file" << endl; + std::deque x; + return x; + } + DRTStructureSetROISequence &roiSequence = + structureSetObject.getStructureSetROISequence(); + if(!roiSequence.gotoFirstItem().good()) + { + MITK_ERROR << "Error reading the structure sequence" << endl; + std::deque x; + return x; + } + do{ + DRTStructureSetROISequence::Item ¤tSequence = + roiSequence.getCurrentItem(); + if(!currentSequence.isValid()) + { + continue; + } + OFString roiName; + OFString roiDescription; + Sint32 roiNumber; + RoiEntry roi; + + currentSequence.getROIName(roiName); + currentSequence.getROIDescription(roiDescription); + currentSequence.getROINumber(roiNumber); + + roi.Name = roiName.c_str(); + roi.Description = roiDescription.c_str(); + roi.Number = roiNumber; + + this->RoiSequenceVector.push_back(roi); + } + while(roiSequence.gotoNextItem().good()); + + Sint32 refRoiNumber; + DRTROIContourSequence &roiContourSeqObject = + structureSetObject.getROIContourSequence(); + if(!roiContourSeqObject.gotoFirstItem().good()) + { + MITK_ERROR << "Error reading the contour sequence" << endl; + std::deque x; + return x; + } + do + { + mitk::ContourModelSet::Pointer contourSet = mitk::ContourModelSet::New(); + DRTROIContourSequence::Item ¤tRoiObject = + roiContourSeqObject.getCurrentItem(); + if(!currentRoiObject.isValid()) + { + continue; + } + currentRoiObject.getReferencedROINumber(refRoiNumber); + DRTContourSequence &contourSeqObject = + currentRoiObject.getContourSequence(); + + if(contourSeqObject.gotoFirstItem().good()) + { + do + { + DRTContourSequence::Item &contourItem = + contourSeqObject.getCurrentItem(); + if(!contourItem.isValid()) + { + continue; + } + int number; + OFString contourNumber; + OFString numberOfPoints; + OFVector contourData_LPS; + mitk::ContourModel::Pointer contourSequence = + mitk::ContourModel::New(); + + contourItem.getContourNumber(contourNumber); + contourItem.getNumberOfContourPoints(numberOfPoints); + contourItem.getContourData(contourData_LPS); + + std::stringstream stream; + stream << numberOfPoints; + stream >> number; + + for(unsigned int i=0; iAddVertex(point); + } + contourSequence->Close(); + contourSet->AddContourModel(contourSequence); + } + while(contourSeqObject.gotoNextItem().good()); + } + else + { + MITK_ERROR << "Error reading contourSeqObject" << endl; + } + RoiEntry* refROI = this->FindRoiByNumber(refRoiNumber); + if(refROI==NULL) + { + MITK_ERROR << "Can not find references ROI" << endl; + continue; + } + Sint32 roiColor; + for(int j=0;j<3;j++) + { + currentRoiObject.getROIDisplayColor(roiColor, j); + refROI->DisplayColor[j] = roiColor/255.0; + } + refROI->ContourModelSet = contourSet; + contourSet->SetProperty("name", mitk::StringProperty::New(refROI->Name)); + contourModelSetVector.push_back(contourSet); + + } + while(roiContourSeqObject.gotoNextItem().good()); + + return contourModelSetVector; + } + + OFString DicomRTReader:: + GetRefFrameOfRefSOPInstanceUID(DRTStructureSetIOD &structSetObject) + { + OFString invalid; + DRTReferencedFrameOfReferenceSequence &refFrameOfRefSeqObject = + structSetObject.getReferencedFrameOfReferenceSequence(); + if(!refFrameOfRefSeqObject.gotoFirstItem().good()) + return invalid; + DRTReferencedFrameOfReferenceSequence::Item ¤tRefFrameOfRefSeqItem = + refFrameOfRefSeqObject.getCurrentItem(); + if(!currentRefFrameOfRefSeqItem.isValid()) + return invalid; + DRTRTReferencedStudySequence &refStudySeqObject = + currentRefFrameOfRefSeqItem.getRTReferencedStudySequence(); + if(!refStudySeqObject.gotoFirstItem().good()) + return invalid; + DRTRTReferencedStudySequence::Item &refStudySeqItem = + refStudySeqObject.getCurrentItem(); + if(!refStudySeqItem.isValid()) + return invalid; + DRTRTReferencedSeriesSequence &refSeriesSeqObject = + refStudySeqItem.getRTReferencedSeriesSequence(); + if(!refSeriesSeqObject.gotoFirstItem().good()) + return invalid; + DRTRTReferencedSeriesSequence::Item &refSeriesSeqItem = + refSeriesSeqObject.getCurrentItem(); + if(!refSeriesSeqItem.isValid()) + return invalid; + DRTContourImageSequence &contourImageSeqObject = + refSeriesSeqItem.getContourImageSequence(); + if(!contourImageSeqObject.gotoFirstItem().good()) + return invalid; + DRTContourImageSequence::Item &contourImageSeqItem = + contourImageSeqObject.getCurrentItem(); + if(!contourImageSeqItem.isValid()) + return invalid; + + OFString resultUid; + contourImageSeqItem.getReferencedSOPInstanceUID(resultUid); + + return resultUid; + } + + mitk::DataNode::Pointer DicomRTReader:: + LoadRTDose(DcmDataset* dataset, char* filename) + { + std::string name = filename; + itk::FilenamesContainer file; + file.push_back(name); + + mitk::DicomSeriesReader* reader = new mitk::DicomSeriesReader; + + mitk::DataNode::Pointer originalNode = reader->LoadDicomSeries(file,false); + + if(originalNode.IsNull()) + { + MITK_ERROR << "Error reading the dcm file" << endl; + return 0; + } + + mitk::Image::Pointer originalImage + = dynamic_cast(originalNode->GetData()); + + DRTDoseIOD doseObject; + OFCondition result = doseObject.read(*dataset); + + if(result.bad()) + { + MITK_ERROR << "Error reading the Dataset" << endl; + return 0; + } + + OFString gridScaling; + Float32 gridscale; + + doseObject.getDoseGridScaling(gridScaling); + gridscale = OFStandard::atof(gridScaling.c_str()); + + AccessByItk_1(originalImage, MultiplayGridScaling, gridscale); + + double prescripeDose = this->GetMaxDoseValue(dataset); + + originalNode->SetName("RT Dose"); + originalNode->SetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescripeDose); + originalNode->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), 40); + originalNode->SetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),true); + return originalNode; + } + + template + void DicomRTReader::MultiplayGridScaling(itk::Image* image, + Float32 gridscale) + { + typedef itk::Image InputImageType; + itk::ImageRegionIterator it(image, + image->GetRequestedRegion()); + for(it=it.Begin(); !it.IsAtEnd(); ++it) + { + it.Set(it.Get()*gridscale); + } + } + + double DicomRTReader::GetMaxDoseValue(DcmDataset* dataSet) + { + DRTDoseIOD doseObject; + OFCondition result = doseObject.read(*dataSet); + if(result.bad()) + { + MITK_ERROR << "Error reading the RT Dose dataset" << endl; + return 0; + } + + Uint16 rows, columns, frames; + OFString nrframes, gridScaling; + const Uint16 *pixelData = NULL; + Float32 gridscale; + + Uint16 &rows_ref = rows; + Uint16 &columns_ref = columns; + + doseObject.getRows(rows_ref); + doseObject.getColumns(columns_ref); + doseObject.getNumberOfFrames(nrframes); + doseObject.getDoseGridScaling(gridScaling); + + frames = atoi(nrframes.c_str()); + gridscale = OFStandard::atof(gridScaling.c_str()); + dataSet->findAndGetUint16Array(DCM_PixelData, pixelData, 0); + + int size = columns*rows*frames; + double highest = 0; + + for(int i=0; ihighest) + { + highest = pixelData[i] * gridscale; + } + } + + return highest; + } + +} diff --git a/Modules/DicomRT/mitkDicomRTReader.h b/Modules/DicomRT/mitkDicomRTReader.h new file mode 100644 index 0000000000..228f1956f8 --- /dev/null +++ b/Modules/DicomRT/mitkDicomRTReader.h @@ -0,0 +1,201 @@ +/*=================================================================== + +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 mitkDicomRTReader_h +#define mitkDicomRTReader_h + +#include +#include +#include +#include +#include "mitkContourModel.h" +#include + +#include "dcmtk/dcmrt/drtstrct.h" +#include "dcmtk/dcmrt/drtdose.h" +#include "dcmtk/dcmrt/drtimage.h" + +#include +#include +#include +#include + +class vtkPolyData; +class DcmDataset; +class OFString; +class DRTContourSequence; +class DRTStructureSetIOD; + +namespace mitk +{ + + class MitkDicomRT_EXPORT DicomRTReader: public itk::Object + { + + typedef std::deque ContourModelSetVector; + + /** + * @brief Describes and holds some information about the beams. + */ + class BeamEntry + { + public: + BeamEntry() + { + Number=-1; + SrcAxisDistance=0.0; + GantryAngle=0.0; + PatientSupportAngle=0.0; + BeamLimitingDeviceAngle=0.0; + LeafJawPositions[0][0]=0.0; + LeafJawPositions[0][1]=0.0; + LeafJawPositions[1][0]=0.0; + LeafJawPositions[1][1]=0.0; + } + unsigned int Number; + std::string Name; + std::string Type; + std::string Description; + double SrcAxisDistance; + double GantryAngle; + double PatientSupportAngle; + double BeamLimitingDeviceAngle; + double LeafJawPositions[2][2]; + }; + + /** + * @brief Describes and holds some information about the Rois. + */ + class RoiEntry + { + public: + RoiEntry(); + virtual ~RoiEntry(); + RoiEntry(const RoiEntry& src); + RoiEntry &operator=(const RoiEntry &src); + + void SetPolyData(ContourModelSet::Pointer roiPolyData); + + unsigned int Number; + std::string Name; + std::string Description; + double DisplayColor[3]; + mitk::ContourModelSet::Pointer ContourModelSet; + }; + + public: + + mitkClassMacro( DicomRTReader, itk::Object ); + itkNewMacro( Self ); + + template + void MultiplayGridScaling( itk::Image< TPixel, VImageDimension>* image, Float32 gridscale); + + void UpdateStdIsolines(Image::Pointer image); + + /** + * @brief Get the maximum dose value from the dose file + * @param dataSet The DcmDataset of the DicomRTDose file + * @return The dose value + * + * Checks all pixel values for the maximum value + */ + double GetMaxDoseValue(DcmDataset* dataSet); + + /** + * @brief Used for reading a DicomRT file + * @param filename The path with your file which you want to read + * + * Calls the right method for reading a dose, structure or plan file. + */ + ContourModelSetVector ReadDicomFile(char* filename); + + /** + * @brief Reads a DcmDataset from a DicomRT structureset file + * @param dataset DcmDataset-object from DCMTK + * @return Returns a Deque with mitk::ContourModelSet + * + * The returned mitk::ContourModelSet represent exactly one + * Roi/Structureset. + * So the size of the returned deque is the number of Rois. The names of the + * rois is stored in their mitk::Property. + */ + ContourModelSetVector ReadStructureSet(DcmDataset* dataset); + + /** + * @brief Reads a DcmDataset from a DicomRT dose file + * @param dataset DcmDataset-object from DCMTK + * @param filename The path with the dose file used for getting the geometry + * @return Returns a mitkDataNode::Pointer in which a mitk::Image is stored + * + * The method reads the PixelData from the DicomRT dose file and scales + * them with a factor for getting Gray-values instead of pixel-values. + * The Gray-values are stored in a mitkImage with a vtkColorTransferFunc. + * Relative values are used for coloring the image. The relative values are + * relative to a PrescriptionDose definied in the RT-Plan. If there is no + * RT-Plan file PrescriptionDose is set to 80% of the maximum dose. + */ + mitk::DataNode::Pointer LoadRTDose(DcmDataset* dataset, char* filename); + + /** + * @brief Returns the number of Rois stored in the RoiSequenceVector + * @return unsigned long size_t Number of Rois + */ + size_t GetNumberOfRois(); + + /** + * @brief Find a Roi stored in the RoiSequenceVector by his number + * @param roiNumber The number of the searched roi + * @return Returns a mitk::DicomRTReader::RoiEntry object + */ + RoiEntry* FindRoiByNumber(unsigned int roiNum); + + /** + * @brief GetReferencedFrameOfReferenceSOPInstanceUID + * @param structSetObject + * @return + */ + OFString GetRefFrameOfRefSOPInstanceUID + (DRTStructureSetIOD &structSetObject); + + /** + * Virtual destructor. + */ + virtual ~DicomRTReader(); + + protected: + + /** + * @brief Storing the Rois found in the Structureset file + */ + std::vector RoiSequenceVector; + + /** + * @brief Storing the Beams foud in the RT Plan file + */ + std::vector BeamSequenceVector; + + /** + * Constructor. + */ + DicomRTReader(); + + }; + +} + +#endif diff --git a/Modules/RTUI/CMakeLists.txt b/Modules/RTUI/CMakeLists.txt new file mode 100644 index 0000000000..f8a8ea7efb --- /dev/null +++ b/Modules/RTUI/CMakeLists.txt @@ -0,0 +1,6 @@ +MITK_CREATE_MODULE( + INCLUDE_DIRS Qmitk Helper + DEPENDS MitkDicomRT MitkQtWidgets MitkQtWidgetsExt + PACKAGE_DEPENDS CTK + QT_MODULE +) diff --git a/Modules/RTUI/Helper/mitkIsoLevelsGenerator.cpp b/Modules/RTUI/Helper/mitkIsoLevelsGenerator.cpp new file mode 100644 index 0000000000..dceba4c132 --- /dev/null +++ b/Modules/RTUI/Helper/mitkIsoLevelsGenerator.cpp @@ -0,0 +1,134 @@ +/*=================================================================== + +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 "mitkIsoLevelsGenerator.h" + +mitk::IsoDoseLevelSet::Pointer mitk::rt::GeneratIsoLevels_Virtuos() +{ + mitk::IsoDoseLevelSet::Pointer levelSet = mitk::IsoDoseLevelSet::New(); + + mitk::IsoDoseLevel::ColorType color; + color[0] = 0.0; + color[1] = 0.0; + color[2] = 0.4; + mitk::IsoDoseLevel::Pointer level = mitk::IsoDoseLevel::New(0.01,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.2; + color[2] = 0.8; + level = mitk::IsoDoseLevel::New(0.1,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.4; + color[2] = 1.0; + level = mitk::IsoDoseLevel::New(0.2,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.7; + color[2] = 1.0; + level = mitk::IsoDoseLevel::New(0.3,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.7; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(0.4,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 1.0; + color[2] = 0.3; + level = mitk::IsoDoseLevel::New(0.5,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 1.0; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(0.6,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 1.0; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.7,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.8; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.8,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.5; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.9,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.4; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.95,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.2; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(1.0,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.0; + color[2] = 0.3; + level = mitk::IsoDoseLevel::New(1.07,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.0; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.1,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.4; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.2,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.7; + color[2] = 0.7; + level = mitk::IsoDoseLevel::New(1.3,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.8; + color[1] = 0.6; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(1.4,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.65; + color[1] = 0.4; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.5,color,true,true); + levelSet->SetIsoDoseLevel(level); + + return levelSet; +} diff --git a/Modules/RTUI/Helper/mitkIsoLevelsGenerator.h b/Modules/RTUI/Helper/mitkIsoLevelsGenerator.h new file mode 100644 index 0000000000..3c42821a6b --- /dev/null +++ b/Modules/RTUI/Helper/mitkIsoLevelsGenerator.h @@ -0,0 +1,33 @@ +/*=================================================================== + +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 __ISO_LEVELS_GENERATOR_H +#define __ISO_LEVELS_GENERATOR_H + +#include "mitkIsoDoseLevelCollections.h" + +#include "MitkRTUIExports.h" + +namespace mitk +{ + namespace rt + { + IsoDoseLevelSet::Pointer MitkRTUI_EXPORT GeneratIsoLevels_Virtuos(); + } +} + +#endif diff --git a/Modules/RTUI/Helper/mitkRTUIConstants.cpp b/Modules/RTUI/Helper/mitkRTUIConstants.cpp new file mode 100644 index 0000000000..6fa6d768af --- /dev/null +++ b/Modules/RTUI/Helper/mitkRTUIConstants.cpp @@ -0,0 +1,45 @@ +/*=================================================================== + +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 "mitkRTUIConstants.h" + +const std::string mitk::rt::UIConstants::ROOT_PREFERENCE_NODE_ID = "/RT/UI"; +const std::string mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_AS_DEFAULT_ID = "unkownDoseHandlingStyle"; +const std::string mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE_ID = "unkownDoseHandlingValue"; + + +const std::string mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID = "/RT/UI/doseVis"; +const std::string mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID = "/RT/UI/doseVis/isoPresets"; +const std::string mitk::rt::UIConstants::REFERENCE_DOSE_ID = "referenceDose"; +const std::string mitk::rt::UIConstants::GLOBAL_REFERENCE_DOSE_SYNC_ID = "globalReferenceDoseSync"; +const std::string mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID = "doseDisplayAbsolute"; +const std::string mitk::rt::UIConstants::GLOBAL_VISIBILITY_ISOLINES_ID = "globalVisibilityIsoLines"; +const std::string mitk::rt::UIConstants::GLOBAL_VISIBILITY_COLORWASH_ID = "globalVisibilityColorWash"; +const std::string mitk::rt::UIConstants::SELECTED_ISO_PRESET_ID = "selectedIsoPreset"; + +const std::string mitk::rt::UIConstants::ISO_LEVEL_DOSE_VALUE_ID = "doseValue"; +const std::string mitk::rt::UIConstants::ISO_LEVEL_COLOR_RED_ID = "color_R"; +const std::string mitk::rt::UIConstants::ISO_LEVEL_COLOR_GREEN_ID = "color_G"; +const std::string mitk::rt::UIConstants::ISO_LEVEL_COLOR_BLUE_ID = "color_B"; +const std::string mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_ISOLINES_ID = "visibleIsoLines"; +const std::string mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_COLORWASH_ID = "visibleColorWash"; + +const mitk::DoseValueAbs mitk::rt::UIConstants::DEFAULT_REFERENCE_DOSE_VALUE = 40.0; + +const std::string mitk::rt::CTKEventConstants::TOPIC_ISO_DOSE_LEVEL_PRESETS = "org/mitk/rt/dosevisualization/presets"; +const std::string mitk::rt::CTKEventConstants::TOPIC_ISO_DOSE_LEVEL_PRESETS_CHANGED = "org/mitk/rt/dosevisualization/presets/CHANGED"; +const std::string mitk::rt::CTKEventConstants::TOPIC_REFERENCE_DOSE = "org/mitk/rt/dosevisualization/referenceDose"; +const std::string mitk::rt::CTKEventConstants::TOPIC_REFERENCE_DOSE_CHANGED = "org/mitk/rt/dosevisualization/referenceDose/CHANGED"; diff --git a/Modules/RTUI/Helper/mitkRTUIConstants.h b/Modules/RTUI/Helper/mitkRTUIConstants.h new file mode 100644 index 0000000000..081177ac0d --- /dev/null +++ b/Modules/RTUI/Helper/mitkRTUIConstants.h @@ -0,0 +1,86 @@ +/*=================================================================== + +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 _MITK_RT_UI_CONSTANTS_H_ +#define _MITK_RT_UI_CONSTANTS_H_ + +#include +#include + +#include "MitkRTUIExports.h" + +namespace mitk +{ + namespace rt + { + struct MitkRTUI_EXPORT UIConstants + { + /** ID/Path of main preference node for RT UI. */ + static const std::string ROOT_PREFERENCE_NODE_ID; + /** Bool that indicates how the prescribed dose should be defined, if unkown. True: UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE should be used as + default dose value in Gy; False: it should be used as fraction of the max dose to determin the prescribed dose.*/ + static const std::string UNKNOWN_PRESCRIBED_DOSE_HANDLING_AS_DEFAULT_ID; + /** Value that is used to determin unknown prescribed doses.*/ + static const std::string UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE_ID; + + /** ID/Path of main preference node where all iso dose level presets are stored (e.g. ROOT_ISO_PRESETS_PREFERENCE_NODE_ID+"/[Preset1]"). */ + static const std::string ROOT_ISO_PRESETS_PREFERENCE_NODE_ID; + /** ID/Path of main preference for dose visualization preferences. */ + static const std::string ROOT_DOSE_VIS_PREFERENCE_NODE_ID; + /** ID for the reference dose stored as preference. */ + static const std::string REFERENCE_DOSE_ID; + /** ID for the preference flag that indicates if the reference dose is synced for all nodes*/ + static const std::string GLOBAL_REFERENCE_DOSE_SYNC_ID; + /** ID for the flag if dose should be displayed as absoulte dose. */ + static const std::string DOSE_DISPLAY_ABSOLUTE_ID; + /** ID for the global visiblity switch for iso line visualization. */ + static const std::string GLOBAL_VISIBILITY_ISOLINES_ID; + /** ID for the global visiblity switch for color wash visualization. */ + static const std::string GLOBAL_VISIBILITY_COLORWASH_ID; + /** ID for the selected iso preset that should be used (value of ROOT_ISO_PRESETS_PREFERENCE_NODE_ID + value of this key can + be used to construct the passed to the selected preset. */ + static const std::string SELECTED_ISO_PRESET_ID; + + /** ID for the relative dose value of an iso dose level. */ + static const std::string ISO_LEVEL_DOSE_VALUE_ID; + /** ID for the color (red component) of an iso dose level. */ + static const std::string ISO_LEVEL_COLOR_RED_ID; + /** ID for the color (green component) of an iso dose level. */ + static const std::string ISO_LEVEL_COLOR_GREEN_ID; + /** ID for the color (blue component) of an iso dose level. */ + static const std::string ISO_LEVEL_COLOR_BLUE_ID; + /** ID for the visiblity switch for iso line visualization. */ + static const std::string ISO_LEVEL_VISIBILITY_ISOLINES_ID; + /** ID for the visiblity switch for color wash visualization. */ + static const std::string ISO_LEVEL_VISIBILITY_COLORWASH_ID; + + /** Default value used as reference_dose_if not defined by application or data node*/ + static const DoseValueAbs DEFAULT_REFERENCE_DOSE_VALUE; + }; + + struct MitkRTUI_EXPORT CTKEventConstants + { + /** ID/Path of main preference node for RT UI. */ + static const std::string TOPIC_REFERENCE_DOSE; + static const std::string TOPIC_REFERENCE_DOSE_CHANGED; + static const std::string TOPIC_ISO_DOSE_LEVEL_PRESETS; + static const std::string TOPIC_ISO_DOSE_LEVEL_PRESETS_CHANGED; + }; + + } +} + +#endif diff --git a/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.cpp b/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.cpp new file mode 100644 index 0000000000..548b5cde00 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.cpp @@ -0,0 +1,83 @@ +/*=================================================================== + +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 "QmitkDoseColorDelegate.h" + +#include +#include +#include +#include +#include +#include + +QmitkDoseColorDelegate::QmitkDoseColorDelegate(QObject * /*parent*/) +{ +} + +void QmitkDoseColorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + + if (data.canConvert()) + { + QColor color = data.value(); + + painter->fillRect(option.rect, color); + } + else + { + QStyledItemDelegate::paint(painter, option, index); + } +} + +bool QmitkDoseColorDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + Q_ASSERT(event); + Q_ASSERT(model); + + // make sure that the item is checkable + Qt::ItemFlags flags = model->flags(index); + if (!(flags & Qt::ItemIsEditable) || !(flags & Qt::ItemIsEnabled)) + { + return false; + } + + // make sure that we have the right event type + QMouseEvent* mouseEvent = dynamic_cast(event); + if (!mouseEvent) + { + return false; + } + else + { + if (mouseEvent->type() != QEvent::MouseButtonRelease || mouseEvent->button() != Qt::LeftButton) + { + return false; + } + } + + QColor oldcolor = index.data(Qt::EditRole).value(); + QColor newColor = QColorDialog::getColor(oldcolor, NULL); + + if (newColor.isValid()) + { + return model->setData(index, QVariant(newColor), Qt::EditRole); + } + + return false; +}; diff --git a/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.h b/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.h new file mode 100644 index 0000000000..78f027f81b --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseColorDelegate.h @@ -0,0 +1,44 @@ +/*=================================================================== + +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 QmitkDoseColorDelegate_h +#define QmitkDoseColorDelegate_h + + +#include + +#include "MitkRTUIExports.h" + +/** \class QmitkDoseColorDelegate +\brief An item delegate for rendering and editing dose color in a QTableView.*/ +class MitkRTUI_EXPORT QmitkDoseColorDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + /// + /// Creates a new PropertyDelegate. + /// + QmitkDoseColorDelegate(QObject *parent = 0); + + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, + const QModelIndex &index); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; +}; + +#endif diff --git a/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.cpp b/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.cpp new file mode 100644 index 0000000000..34ed4b28eb --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.cpp @@ -0,0 +1,113 @@ +/*=================================================================== + +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 "QmitkDoseValueDelegate.h" + +#include +#include +#include +#include + +QmitkDoseValueDelegate::QmitkDoseValueDelegate(QObject * /*parent*/) +{ +} + +void QmitkDoseValueDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::DisplayRole); + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + + QStyle *style = QApplication::style(); + + + style->drawItemText(painter, opt.rect.adjusted(0,0,-5,0), Qt::AlignRight | Qt::AlignVCenter, opt.palette,true, data.toString()); +} + +QWidget* QmitkDoseValueDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + QVariant absoluteDose = index.data(Qt::UserRole+1); + + if(data.isValid()) + { + QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); + spinBox->setDecimals(2); + if (absoluteDose.toBool()) + { + spinBox->setSingleStep(0.5); + spinBox->setSuffix(QString(" Gy")); + } + else + { + spinBox->setSingleStep(1.0); + spinBox->setSuffix(QString(" %")); + } + + spinBox->setMinimum(0.0); + spinBox->setMaximum(9999.0); + + spinBox->installEventFilter( const_cast(this) ); + + return spinBox; + + } + else + return new QLabel(displayData.toString(), parent); + +} + +void QmitkDoseValueDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + + if(data.isValid()) + { + + QDoubleSpinBox* spinBox = qobject_cast(editor); + if (spinBox) + { + spinBox->setValue(data.toDouble()); + } + else + { + QStyledItemDelegate::setEditorData(editor, index); + } + } +} + +void QmitkDoseValueDelegate::setModelData(QWidget *editor, QAbstractItemModel* model + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + + if(data.isValid()) + { + QDoubleSpinBox* spinBox = qobject_cast(editor); + double doubleValue = spinBox->value(); + + QVariant doubleValueVariant(doubleValue); + model->setData(index, doubleValueVariant); + } + else + { + QStyledItemDelegate::setModelData(editor, model, index); + } +} diff --git a/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.h b/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.h new file mode 100644 index 0000000000..5116d84c62 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseValueDelegate.h @@ -0,0 +1,63 @@ +/*=================================================================== + +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 QmitkDoseValueDelegate_h +#define QmitkDoseValueDelegate_h + + +#include + +#include "MitkRTUIExports.h" + +/** \class QmitkDoseValueDelegate +\brief An item delegate for rendering and editing dose values. +The delegate assumes that the model uses the role Qt::UserRole+1 +to indicate if the returned dose value is an absolute (data(Qt::UserRole+1) == true) +or an relative dose (data(Qt::UserRole+1) == false).*/ +class MitkRTUI_EXPORT QmitkDoseValueDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + /// + /// Creates a new PropertyDelegate. + /// + QmitkDoseValueDelegate(QObject *parent = 0); + + /// + /// Renders a specific property (overwritten from QItemDelegate) + /// + void paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + /// + /// When the user accepts input this func commits the data to the model (overwritten from QItemDelegate) + /// + void setModelData(QWidget *editor, QAbstractItemModel* model, const QModelIndex &index) const; +}; + +#endif /* QMITKPROPERTIESTABLEMODEL_H_ */ diff --git a/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.cpp b/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.cpp new file mode 100644 index 0000000000..9de4f0b4c8 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.cpp @@ -0,0 +1,94 @@ +/*=================================================================== + +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 "QmitkDoseVisualStyleDelegate.h" + +#include +#include +#include +#include +#include + +static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) { + QStyleOptionButton check_box_style_option; + QRect check_box_rect = QApplication::style()->subElementRect( + QStyle::SE_CheckBoxIndicator, + &check_box_style_option); + QPoint check_box_point(view_item_style_options.rect.x() + + view_item_style_options.rect.width() / 2 - + check_box_rect.width() / 2, + view_item_style_options.rect.y() + + view_item_style_options.rect.height() / 2 - + check_box_rect.height() / 2); + return QRect(check_box_point, check_box_rect.size()); +} + +QmitkDoseVisualStyleDelegate::QmitkDoseVisualStyleDelegate(QObject * /*parent*/) +{ +} + +void QmitkDoseVisualStyleDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + bool checkValue = index.data(Qt::DisplayRole).toBool(); + + QStyleOptionButton BtnStyle; + BtnStyle.state = QStyle::State_Enabled; + + if(checkValue) + { + BtnStyle.state |= QStyle::State_On; + } + else + { + BtnStyle.state |= QStyle::State_Off; + } + + BtnStyle.direction = QApplication::layoutDirection(); + BtnStyle.rect = CheckBoxRect(option); + QApplication::style()->drawControl(QStyle::CE_CheckBox,&BtnStyle,painter ); +} + +bool QmitkDoseVisualStyleDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + Q_ASSERT(event); + Q_ASSERT(model); + + // make sure that the item is checkable + Qt::ItemFlags flags = model->flags(index); + if (!(flags & Qt::ItemIsEditable) || !(flags & Qt::ItemIsEnabled)) + { + return false; + } + + // make sure that we have the right event type + QMouseEvent* mouseEvent = dynamic_cast(event); + if (!mouseEvent) + { + return false; + } + else + { + if (mouseEvent->type() != QEvent::MouseButtonRelease || mouseEvent->button() != Qt::LeftButton) + { + return false; + } + } + + bool newState = !(index.data(Qt::EditRole).toBool()); + + return model->setData(index, QVariant(newState), Qt::EditRole); +}; diff --git a/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.h b/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.h new file mode 100644 index 0000000000..7032fd11d0 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkDoseVisualStyleDelegate.h @@ -0,0 +1,47 @@ +/*=================================================================== + +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 QmitkDoseVisualStyleDelegate_h +#define QmitkDoseVisualStyleDelegate_h + + +/// Toolkit includes. +#include + +#include "MitkRTUIExports.h" + + +/** \class QmitkDoseVisualStyleDelegate +\brief An item delegate for rendering and editing dose visualization options. +The delegate is used to handle aspects of a isodose level like visualization +of the isodose lines or colorwash display.*/ +class MitkRTUI_EXPORT QmitkDoseVisualStyleDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + + QmitkDoseVisualStyleDelegate(QObject *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, + const QModelIndex &index); + +}; + +#endif diff --git a/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.cpp b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.cpp new file mode 100644 index 0000000000..0a313dbedd --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.cpp @@ -0,0 +1,145 @@ +/*=================================================================== + +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 "QmitkFreeIsoDoseLevelWidget.h" + + +QmitkFreeIsoDoseLevelWidget::QmitkFreeIsoDoseLevelWidget(QWidget*): m_ReferenceDose (40.0), m_InternalUpdate(false) +{ + this->setupUi(this); + + this->colorBtn->setDisplayColorName(false); + this->m_IsoDoseLevel = mitk::IsoDoseLevel::New(); + + connect(this->sbAbsValue, SIGNAL(valueChanged(double)), this, SLOT(OnAbsValueChanged(double))); + connect(this->sbRelValue, SIGNAL(valueChanged(double)), this, SLOT(OnRelValueChanged(double))); + connect(this->doseSlider, SIGNAL(valueChanged(int)), this, SLOT(OnSliderChanged(int))); + connect(this->checkVisibleIso, SIGNAL(clicked(bool)), this, SLOT(OnVisibleClicked(bool))); + connect(this->colorBtn, SIGNAL(colorChanged(QColor)), this, SLOT(OnColorChanged(QColor))); +} + +mitk::DoseValueAbs + QmitkFreeIsoDoseLevelWidget:: + getReferenceDose() const +{ + return this->m_ReferenceDose; +}; + +mitk::IsoDoseLevel* + QmitkFreeIsoDoseLevelWidget:: + getIsoDoseLevel() const +{ + return this->m_IsoDoseLevel; +}; + +void QmitkFreeIsoDoseLevelWidget:: + setReferenceDose(double newReferenceDose) +{ + if (newReferenceDose != m_ReferenceDose) + { + this->m_ReferenceDose = newReferenceDose; + this->update(); + } +}; + +void QmitkFreeIsoDoseLevelWidget:: + setIsoDoseLevel(mitk::IsoDoseLevel* level) +{ + if (level != m_IsoDoseLevel) + { + if(!level) + { + mitkThrow() << "Error. Cannot set iso dose level for widget to NULL pointer."; + } + + this->m_IsoDoseLevel = level; + this->update(); + } +} + +void QmitkFreeIsoDoseLevelWidget:: + OnRelValueChanged(double newValue) +{ + if(!m_InternalUpdate) + { + updateValue(newValue/100.0); + } +}; + +void QmitkFreeIsoDoseLevelWidget:: + OnAbsValueChanged(double newValue) +{ + if(!m_InternalUpdate) + { + updateValue(newValue/this->m_ReferenceDose); + } +}; + +void QmitkFreeIsoDoseLevelWidget:: + OnSliderChanged(int newValue) +{ + if(!m_InternalUpdate) + { + updateValue(newValue/100.0); + } +}; + +void QmitkFreeIsoDoseLevelWidget:: + OnVisibleClicked(bool checked) +{ + this->m_IsoDoseLevel->SetVisibleIsoLine(checked); + emit VisualizationStyleChanged(this->m_IsoDoseLevel); +}; + +void QmitkFreeIsoDoseLevelWidget:: + OnColorChanged(QColor color) +{ + mitk::IsoDoseLevel::ColorType doseColor; + doseColor.SetRed(color.redF()); + doseColor.SetGreen(color.greenF()); + doseColor.SetBlue(color.blueF()); + this->m_IsoDoseLevel->SetColor(doseColor); + emit ColorChanged(this->m_IsoDoseLevel); +}; + +void QmitkFreeIsoDoseLevelWidget:: + updateValue(mitk::DoseValueRel newDose) +{ + m_InternalUpdate = true; + + mitk::DoseValueRel oldValue = this->m_IsoDoseLevel->GetDoseValue(); + this->m_IsoDoseLevel->SetDoseValue(newDose); + this->sbAbsValue->setValue(newDose*this->m_ReferenceDose); + this->sbRelValue->setValue(newDose*100); + this->doseSlider->setValue(newDose*100); + + m_InternalUpdate = false; + + emit ValueChanged(this->m_IsoDoseLevel,oldValue); +}; + +void QmitkFreeIsoDoseLevelWidget:: + update() +{ + updateValue(this->m_IsoDoseLevel->GetDoseValue()); + + this->checkVisibleIso->setChecked(this->m_IsoDoseLevel->GetVisibleIsoLine()); + + QColor color; + color.setRgbF(this->m_IsoDoseLevel->GetColor().GetRed(),this->m_IsoDoseLevel->GetColor().GetGreen(),this->m_IsoDoseLevel->GetColor().GetBlue()); + this->colorBtn->setColor(color); +}; diff --git a/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.h b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.h new file mode 100644 index 0000000000..8973071578 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.h @@ -0,0 +1,78 @@ +/*=================================================================== + +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 QMITK_FREE_ISO_DOSE_LEVEL_WIDGET_H +#define QMITK_FREE_ISO_DOSE_LEVEL_WIDGET_H + +#include "MitkRTUIExports.h" + +#include "ui_QmitkFreeIsoDoseLevelWidget.h" +#include + +#include "mitkIsoDoseLevel.h" + +/** +* \class QmitkFreeIsoDoseLevelWidget +* \brief Widget that allows to show and edit the content of an mitk::IsoDoseLevel instance. +*/ +class MitkRTUI_EXPORT QmitkFreeIsoDoseLevelWidget : public QWidget, private Ui::QmitkFreeIsoDoseLevelWidget +{ + Q_OBJECT + +public: + QmitkFreeIsoDoseLevelWidget(QWidget* parent=0); + + mitk::DoseValueAbs getReferenceDose() const; + mitk::IsoDoseLevel* getIsoDoseLevel() const; + +signals: + void ValueChanged(mitk::IsoDoseLevel*, mitk::DoseValueRel oldValue); + void ColorChanged(mitk::IsoDoseLevel*); + void VisualizationStyleChanged(mitk::IsoDoseLevel*); + + public Q_SLOTS: + /** + * \brief Slot that can be used to set the reference dose. + */ + void setReferenceDose(double newReferenceDose); + + /** + * \brief Slot that can be used to set the dose level instance that should be handled by the widget. + */ + void setIsoDoseLevel(mitk::IsoDoseLevel* level); + + void OnRelValueChanged(double newValue); + void OnAbsValueChanged(double newValue); + void OnSliderChanged(int newValue); + void OnVisibleClicked(bool checked); + void OnColorChanged(QColor color); + +protected: + + /** + * \brief Updates the widget according to its current settings. + */ + void update(); + void updateValue(mitk::DoseValueRel newDose); + + mitk::DoseValueAbs m_ReferenceDose; + mitk::IsoDoseLevel::Pointer m_IsoDoseLevel; + bool m_InternalUpdate; + +}; + +#endif // QmitkFreeIsoDoseLevelWidget_H diff --git a/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.ui b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.ui new file mode 100644 index 0000000000..1f168c8044 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkFreeIsoDoseLevelWidget.ui @@ -0,0 +1,201 @@ + + + QmitkFreeIsoDoseLevelWidget + + + + 0 + 0 + 395 + 32 + + + + Form + + + + 2 + + + + + + 0 + 0 + + + + + 40 + 16777215 + + + + Color of the iso dose level + + + + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + 150 + + + Qt::Horizontal + + + false + + + false + + + QSlider::NoTicks + + + 0 + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + % + + + 9999.000000000000000 + + + 0.500000000000000 + + + + + + + = + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + Minimum dose value of this level. + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Gy + + + 9999.000000000000000 + + + 0.500000000000000 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 50 + 16777215 + + + + Show isoline for this dose level + + + Qt::LeftToRight + + + + + + + :/RTUI/eye_open.png + :/RTUI/eye_open.png + :/RTUI/eye_open.png:/RTUI/eye_open.png + + + + 24 + 16 + + + + false + + + + + + + + ctkColorPickerButton + QPushButton +
ctkColorPickerButton.h
+
+
+ + + + +
diff --git a/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.cpp b/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.cpp new file mode 100644 index 0000000000..8b0bcdcd7e --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.cpp @@ -0,0 +1,450 @@ +/*=================================================================== + +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 +#include + +#include "QmitkIsoDoseLevelSetModel.h" +#include "mitkRTUIConstants.h" + +QmitkIsoDoseLevelSetModel:: + QmitkIsoDoseLevelSetModel(QObject *parent) : +QAbstractTableModel(parent), m_referenceDose(mitk::rt::UIConstants::DEFAULT_REFERENCE_DOSE_VALUE), m_showAbsoluteDose(false), m_visibilityEditOnly(false), m_modified(false) +{ + m_DoseSet = mitk::IsoDoseLevelSet::New(); +} + +void + QmitkIsoDoseLevelSetModel:: + setIsoDoseLevelSet(mitk::IsoDoseLevelSet *pSet) +{ + if (pSet) + { + emit beginResetModel(); + + m_DoseSet = pSet; + m_modified = false; + + emit endResetModel(); + } +}; + +int + QmitkIsoDoseLevelSetModel:: + rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + { + return 0; + } + + return m_DoseSet->Size(); +} + +int + QmitkIsoDoseLevelSetModel:: + columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return 4; +} + +QVariant + QmitkIsoDoseLevelSetModel:: + data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + QVariant result; + + if(index.row()Size()) + { + const mitk::IsoDoseLevel& level = m_DoseSet->GetIsoDoseLevel(static_cast(index.row())); + + switch(index.column()) + { + case 0: + if(role == Qt::EditRole || role == Qt::DecorationRole) + { + QColor color; + color.setRgbF(level.GetColor().GetRed(),level.GetColor().GetGreen(),level.GetColor().GetBlue()); + result = QVariant(color); + } + else if (role == Qt::ToolTipRole) + { + result = QVariant("Color of the iso dose level."); + } + break; + case 1: + if(role == Qt::DisplayRole) + { + if (this->m_showAbsoluteDose) + { + result = QVariant(QString::number(level.GetDoseValue()*this->m_referenceDose)+QString(" Gy")); + } + else + { + result = QVariant(QString::number(level.GetDoseValue()*100)+QString(" %")); + } + } + else if(role == Qt::EditRole) + { + if (this->m_showAbsoluteDose) + { + result = QVariant(level.GetDoseValue()*this->m_referenceDose); + } + else + { + result = QVariant(level.GetDoseValue()*100); + } + } + else if (role == Qt::ToolTipRole) + { + result = QVariant("Minimum dose value of this level / Value of the iso line."); + } + else if (role == Qt::UserRole+1) + { + result = QVariant(this->m_showAbsoluteDose); + } + break; + case 2: + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + result = QVariant(level.GetVisibleIsoLine()); + } + else if (role == Qt::ToolTipRole) + { + result = QVariant("Show isoline for this dose level."); + } + break; + case 3: + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + result = QVariant(level.GetVisibleColorWash()); + } + else if (role == Qt::ToolTipRole) + { + result = QVariant("Show colorwash for this dose level."); + } + break; + } + } + + return result; +} + +Qt::ItemFlags + QmitkIsoDoseLevelSetModel:: + flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if(index.row()Size()) + { + if (index.column() < 4) + { + if ((index.column() > 1) || (index.column() >= 0 && !this->m_visibilityEditOnly)) + { + flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + } + else if (index.column() >= 0 && this->m_visibilityEditOnly) + { + flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + + } + } + + return flags; +} + +QVariant + QmitkIsoDoseLevelSetModel:: + headerData(int section, Qt::Orientation orientation, int role) const +{ + if( (Qt::DisplayRole == role) && + (Qt::Horizontal == orientation)) + { + if (section==0) + { + return QVariant("Color"); + } + else if (section==1) + { + if (m_showAbsoluteDose) + { + return QVariant("Dose [Gy]"); + } + else + { + return QVariant("Dose [%]"); + } + } + else if (section==2) + { + return QVariant("IsoLines"); + } + else if (section==3) + { + return QVariant("ColorWash"); + } + } + return QVariant(); +} + +bool + QmitkIsoDoseLevelSetModel:: + setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid() || (m_DoseSet->Size() <= index.row()) || (index.column()>3)) + { + return false; + } + + if(Qt::EditRole == role) + { + const mitk::IsoDoseLevel& level = m_DoseSet->GetIsoDoseLevel(static_cast(index.row())); + mitk::IsoDoseLevel::Pointer pNewLevel = level.Clone(); + switch(index.column()) + { + case 0: + { + QColor val = value.value(); + mitk::IsoDoseLevel::ColorType color; + color.SetRed(val.redF()); + color.SetGreen(val.greenF()); + color.SetBlue(val.blueF()); + pNewLevel->SetColor(color); + emit dataChanged(index,index); + break; + } + case 1: + if (this->m_showAbsoluteDose) + { + pNewLevel->SetDoseValue(value.toDouble()/this->m_referenceDose); + } + else + { + pNewLevel->SetDoseValue(value.toDouble()/100.0); + } + emit dataChanged(index,index); + break; + case 2: + pNewLevel->SetVisibleIsoLine(value.toBool()); + emit dataChanged(index,index); + break; + case 3: + pNewLevel->SetVisibleColorWash(value.toBool()); + emit dataChanged(index,index); + break; + } + + emit beginResetModel(); + + m_DoseSet->DeleteIsoDoseLevel(static_cast(index.row())); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + + m_modified = true; + + emit endResetModel(); + + return true; + } + + return false; +}; + +void QmitkIsoDoseLevelSetModel:: + setReferenceDose(double newReferenceDose) +{ + if (newReferenceDose<= 0) + { + mitkThrow() << "Error. Passed prescribed dose is negative or equals 0."; + } + + if (newReferenceDose != m_referenceDose) + { + this->m_referenceDose = newReferenceDose; + if(m_showAbsoluteDose) + { + emit beginResetModel(); + emit endResetModel(); + } + } +}; + +void QmitkIsoDoseLevelSetModel:: + setShowAbsoluteDose(bool showAbsoluteDose) + +{ + if (showAbsoluteDose != m_showAbsoluteDose) + { + emit beginResetModel(); + this->m_showAbsoluteDose = showAbsoluteDose; + emit endResetModel(); + } +}; + +void QmitkIsoDoseLevelSetModel::setVisibilityEditOnly(bool onlyVisibility) +{ + if (onlyVisibility != m_visibilityEditOnly) + { + emit beginResetModel(); + this->m_visibilityEditOnly = onlyVisibility; + emit endResetModel(); + } +}; + +bool + QmitkIsoDoseLevelSetModel:: + getShowAbsoluteDose() const +{ + return this->m_showAbsoluteDose; +}; + +mitk::DoseValueAbs + QmitkIsoDoseLevelSetModel:: + getReferenceDose() const +{ + return this->m_referenceDose; +}; + +bool + QmitkIsoDoseLevelSetModel:: + getVisibilityEditOnly() const +{ + return this->m_visibilityEditOnly; +}; + +void QmitkIsoDoseLevelSetModel::switchVisibilityIsoLines(bool activate) +{ + emit beginResetModel(); + + for (mitk::IsoDoseLevelSet::IsoLevelIndexType pos = 0; pos < m_DoseSet->Size(); ++pos) + { + mitk::IsoDoseLevel::Pointer pNewLevel = m_DoseSet->GetIsoDoseLevel(pos).Clone(); + pNewLevel->SetVisibleIsoLine(activate); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + } + + m_modified = true; + + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::switchVisibilityColorWash(bool activate) +{ + emit beginResetModel(); + + for (mitk::IsoDoseLevelSet::IsoLevelIndexType pos = 0; pos < m_DoseSet->Size(); ++pos) + { + mitk::IsoDoseLevel::Pointer pNewLevel = m_DoseSet->GetIsoDoseLevel(pos).Clone(); + pNewLevel->SetVisibleColorWash(activate); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + } + + m_modified = true; + + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::invertVisibilityIsoLines() +{ + emit beginResetModel(); + + for (mitk::IsoDoseLevelSet::IsoLevelIndexType pos = 0; pos < m_DoseSet->Size(); ++pos) + { + mitk::IsoDoseLevel::Pointer pNewLevel = m_DoseSet->GetIsoDoseLevel(pos).Clone(); + pNewLevel->SetVisibleIsoLine(!pNewLevel->GetVisibleIsoLine()); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + } + + m_modified = true; + + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::invertVisibilityColorWash() +{ + emit beginResetModel(); + + for (mitk::IsoDoseLevelSet::IsoLevelIndexType pos = 0; pos < m_DoseSet->Size(); ++pos) + { + mitk::IsoDoseLevel::Pointer pNewLevel = m_DoseSet->GetIsoDoseLevel(pos).Clone(); + pNewLevel->SetVisibleColorWash(!pNewLevel->GetVisibleColorWash()); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + } + + m_modified = true; + + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::swapVisibility() +{ + emit beginResetModel(); + + for (mitk::IsoDoseLevelSet::IsoLevelIndexType pos = 0; pos < m_DoseSet->Size(); ++pos) + { + mitk::IsoDoseLevel::Pointer pNewLevel = m_DoseSet->GetIsoDoseLevel(pos).Clone(); + bool colorWash = pNewLevel->GetVisibleColorWash(); + pNewLevel->SetVisibleColorWash(pNewLevel->GetVisibleIsoLine()); + pNewLevel->SetVisibleIsoLine(colorWash); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + } + + m_modified = true; + + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::addLevel() +{ + mitk::IsoDoseLevel::DoseValueType doseVal = 0.01; + + if (m_DoseSet->Size()>0) + { + doseVal = m_DoseSet->GetIsoDoseLevel(m_DoseSet->Size()-1).GetDoseValue()+0.01; + } + + mitk::IsoDoseLevel::Pointer pNewLevel = mitk::IsoDoseLevel::New(doseVal, mitk::IsoDoseLevel::ColorType(), true, true); + + emit beginResetModel(); + m_DoseSet->SetIsoDoseLevel(pNewLevel); + m_modified = true; + emit endResetModel(); +} + +void QmitkIsoDoseLevelSetModel::deleteLevel(const QModelIndex &index) +{ + if(!index.isValid() || (m_DoseSet->Size() <= index.row()) || (index.column()>3)) + { + return; + } + + emit beginResetModel(); + m_DoseSet->DeleteIsoDoseLevel(static_cast(index.row())); + m_modified = true; + emit endResetModel(); +} + +bool QmitkIsoDoseLevelSetModel::isModified() +{ + return m_modified; +} diff --git a/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.h b/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.h new file mode 100644 index 0000000000..0940072072 --- /dev/null +++ b/Modules/RTUI/Qmitk/QmitkIsoDoseLevelSetModel.h @@ -0,0 +1,98 @@ +/*=================================================================== + +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 QmitkIsoDoseLevelSetModel_h +#define QmitkIsoDoseLevelSetModel_h + +#include + +#include "mitkIsoDoseLevelCollections.h" + +#include "MitkRTUIExports.h" + + +/*! +\class QmitkIsoDoseLevelSetModel +Model that handles a iso dose level set and allows viewing and editing of its contents. +Please see special delegates (QmitkDoseColorDelegate, QmitkDoseValueDelegate, QmitkDoseVisualStyleDelegate) to +handle visualization and editing in views that work on this model. +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MitkRTUI_EXPORT QmitkIsoDoseLevelSetModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + QmitkIsoDoseLevelSetModel(QObject *parent = NULL); + virtual ~QmitkIsoDoseLevelSetModel() {}; + + /** Sets the data handled by the model and resets the modified flag*/ + void setIsoDoseLevelSet(mitk::IsoDoseLevelSet *pSet); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + bool getShowAbsoluteDose() const; + mitk::DoseValueAbs getReferenceDose() const; + + bool getVisibilityEditOnly() const; + + void switchVisibilityIsoLines(bool activate); + void switchVisibilityColorWash(bool activate); + void invertVisibilityIsoLines(); + void invertVisibilityColorWash(); + void swapVisibility(); + + void addLevel(); + void deleteLevel(const QModelIndex &index); + + /**Indicates if the content of the model was modified since the data was set via setIsoDoseLevelSet()*/ + bool isModified(); + + public Q_SLOTS: + /** + * \brief Slot that can be used to set the prescribed dose. + */ + void setReferenceDose(double newReferenceDose); + /** + * \brief Slot that can be used to adjust whether the dose should be displayed in absolute or relative units. + */ + void setShowAbsoluteDose(bool showAbsoluteDose); + + /** + * \brief Slat that can be used to adjust wether the model allows to edit only visibilities (no dose value or color) + */ + void setVisibilityEditOnly(bool onlyVisibility); + +private: + mitk::IsoDoseLevelSet::Pointer m_DoseSet; + + bool m_showAbsoluteDose; + bool m_visibilityEditOnly; + + mitk::DoseValueAbs m_referenceDose; + + /** Indicates if the data of the model was modified, since the model was set. */ + bool m_modified; + +}; + +#endif // QmitkIsoDoseLevelSetModel_h + diff --git a/Modules/RTUI/files.cmake b/Modules/RTUI/files.cmake new file mode 100644 index 0000000000..d49a968f4c --- /dev/null +++ b/Modules/RTUI/files.cmake @@ -0,0 +1,27 @@ +set(CPP_FILES + Qmitk/QmitkFreeIsoDoseLevelWidget.cpp + Qmitk/QmitkIsoDoseLevelSetModel.cpp + Qmitk/QmitkDoseColorDelegate.cpp + Qmitk/QmitkDoseValueDelegate.cpp + Qmitk/QmitkDoseVisualStyleDelegate.cpp + Helper/mitkRTUIConstants.cpp + Helper/mitkIsoLevelsGenerator.cpp +) + +set(UI_FILES + Qmitk/QmitkFreeIsoDoseLevelWidget.ui +) + +set(MOC_H_FILES + Qmitk/QmitkFreeIsoDoseLevelWidget.h + Qmitk/QmitkIsoDoseLevelSetModel.h + Qmitk/QmitkDoseColorDelegate.h + Qmitk/QmitkDoseValueDelegate.h + Qmitk/QmitkDoseVisualStyleDelegate.h +) + +set(QRC_FILES + resources/RTUI.qrc +) + + diff --git a/Modules/RTUI/resources/RTUI.qrc b/Modules/RTUI/resources/RTUI.qrc new file mode 100644 index 0000000000..174c9563ea --- /dev/null +++ b/Modules/RTUI/resources/RTUI.qrc @@ -0,0 +1,8 @@ + + + powerGreen.png + eye_close.png + eye_open.png + powerRed.png + + diff --git a/Modules/RTUI/resources/eye_close.png b/Modules/RTUI/resources/eye_close.png new file mode 100644 index 0000000000..9b82203c2a Binary files /dev/null and b/Modules/RTUI/resources/eye_close.png differ diff --git a/Modules/RTUI/resources/eye_open.png b/Modules/RTUI/resources/eye_open.png new file mode 100644 index 0000000000..a1c2bb9f35 Binary files /dev/null and b/Modules/RTUI/resources/eye_open.png differ diff --git a/Modules/RTUI/resources/powerGreen.png b/Modules/RTUI/resources/powerGreen.png new file mode 100644 index 0000000000..9e8e0903d9 Binary files /dev/null and b/Modules/RTUI/resources/powerGreen.png differ diff --git a/Modules/RTUI/resources/powerRed.png b/Modules/RTUI/resources/powerRed.png new file mode 100644 index 0000000000..bb3f33bef5 Binary files /dev/null and b/Modules/RTUI/resources/powerRed.png differ diff --git a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp index 5b9f6016e5..d7e736924f 100644 --- a/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp +++ b/Modules/Segmentation/Interactions/mitkFeedbackContourTool.cpp @@ -1,136 +1,136 @@ /*=================================================================== 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 "mitkFeedbackContourTool.h" #include "mitkToolManager.h" #include "mitkProperties.h" #include "mitkStringProperty.h" #include "mitkColorProperty.h" #include "mitkDataStorage.h" #include "mitkBaseRenderer.h" #include "mitkRenderingManager.h" mitk::FeedbackContourTool::FeedbackContourTool(const char* type) :SegTool2D(type), m_FeedbackContourVisible(false) { m_FeedbackContour = ContourModel::New(); m_FeedbackContour->SetClosed(true); m_FeedbackContourNode = DataNode::New(); m_FeedbackContourNode->SetData( m_FeedbackContour ); m_FeedbackContourNode->SetProperty("name", StringProperty::New("One of FeedbackContourTool's feedback nodes")); m_FeedbackContourNode->SetProperty("visible", BoolProperty::New(true)); m_FeedbackContourNode->SetProperty("helper object", BoolProperty::New(true)); m_FeedbackContourNode->SetProperty("layer", IntProperty::New(1000)); m_FeedbackContourNode->SetProperty("contour.project-onto-plane", BoolProperty::New(false)); m_FeedbackContourNode->SetProperty("contour.width", FloatProperty::New(1.0)); this->Disable3dRendering(); SetFeedbackContourColorDefault(); } mitk::FeedbackContourTool::~FeedbackContourTool() { } void mitk::FeedbackContourTool::SetFeedbackContourColor( float r, float g, float b ) { - m_FeedbackContourNode->SetProperty("contour.color", ColorProperty::New(r, g, b)); + m_FeedbackContourNode->SetProperty("color", ColorProperty::New(r, g, b)); } void mitk::FeedbackContourTool::SetFeedbackContourColorDefault() { - m_FeedbackContourNode->SetProperty("contour.color", ColorProperty::New(0.0/255.0, 255.0/255.0, 0.0/255.0)); + m_FeedbackContourNode->SetProperty("color", ColorProperty::New(0.0/255.0, 255.0/255.0, 0.0/255.0)); } mitk::ContourModel* mitk::FeedbackContourTool::GetFeedbackContour() { return m_FeedbackContour; } void mitk::FeedbackContourTool::SetFeedbackContour(ContourModel& contour) { // begin of temporary fix for 3m3 release this->Disable3dRendering(); //end of temporary fix for 3m3 release m_FeedbackContour = &contour; m_FeedbackContourNode->SetData( m_FeedbackContour ); } void mitk::FeedbackContourTool::SetFeedbackContourVisible(bool visible) { // begin of temporary fix for 3m3 release this->Disable3dRendering(); //end of temporary fix for 3m3 release if ( m_FeedbackContourVisible == visible ) return; // nothing changed if ( DataStorage* storage = m_ToolManager->GetDataStorage() ) { if (visible) { storage->Add( m_FeedbackContourNode ); } else { storage->Remove( m_FeedbackContourNode ); } } m_FeedbackContourVisible = visible; } mitk::ContourModel::Pointer mitk::FeedbackContourTool::ProjectContourTo2DSlice(Image* slice, ContourModel* contourIn3D, bool correctionForIpSegmentation, bool constrainToInside) { return mitk::ContourModelUtils::ProjectContourTo2DSlice(slice, contourIn3D, correctionForIpSegmentation, constrainToInside); } mitk::ContourModel::Pointer mitk::FeedbackContourTool::BackProjectContourFrom2DSlice(const Geometry3D* sliceGeometry, ContourModel* contourIn2D, bool correctionForIpSegmentation) { return mitk::ContourModelUtils::BackProjectContourFrom2DSlice(sliceGeometry, contourIn2D, correctionForIpSegmentation); } void mitk::FeedbackContourTool::FillContourInSlice( ContourModel* projectedContour, Image* sliceImage, int paintingPixelValue ) { this->FillContourInSlice(projectedContour, 0, sliceImage, paintingPixelValue); } void mitk::FeedbackContourTool::FillContourInSlice( ContourModel* projectedContour, unsigned int timeStep, Image* sliceImage, int paintingPixelValue ) { mitk::ContourModelUtils::FillContourInSlice(projectedContour, timeStep, sliceImage, paintingPixelValue); } void mitk::FeedbackContourTool::Disable3dRendering() { // set explicitly visible=false for all 3D renderer (that exist already ...) const RenderingManager::RenderWindowVector& renderWindows = RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); for (RenderingManager::RenderWindowVector::const_iterator iter = renderWindows.begin(); iter != renderWindows.end(); ++iter) { if ( mitk::BaseRenderer::GetInstance((*iter))->GetMapperID() == BaseRenderer::Standard3D ) //if ( (*iter)->GetRenderer()->GetMapperID() == BaseRenderer::Standard3D ) { m_FeedbackContourNode->SetProperty("visible", BoolProperty::New(false), mitk::BaseRenderer::GetInstance((*iter))); } } } diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp index 4c72aa88dd..0ce9f6e381 100644 --- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp +++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp @@ -1,666 +1,666 @@ /*=================================================================== 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 #include #include #include #include #include #include #include #include #include #include #include #include #include "mitkLiveWireTool2D.h" #include "mitkLiveWireTool2D.xpm" namespace mitk { MITK_TOOL_MACRO(MitkSegmentation_EXPORT, LiveWireTool2D, "LiveWire tool"); } static void AddInteractorToGlobalInteraction(mitk::Interactor* interactor) { mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor); } static void RemoveInteractorFromGlobalInteraction(mitk::Interactor* interactor) { mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor); } class RemoveFromDataStorage { public: RemoveFromDataStorage(mitk::DataStorage::Pointer dataStorage) : m_DataStorage(dataStorage) { } void operator()(mitk::DataNode* dataNode) { m_DataStorage->Remove(dataNode); } void operator()(const std::pair& dataNode) { m_DataStorage->Remove(dataNode.first); } private: mitk::DataStorage::Pointer m_DataStorage; }; mitk::LiveWireTool2D::LiveWireTool2D() : SegTool2D("LiveWireTool") { } mitk::LiveWireTool2D::~LiveWireTool2D() { this->ClearSegmentation(); } void mitk::LiveWireTool2D::RemoveHelperObjects() { DataStorage* dataStorage = m_ToolManager->GetDataStorage(); if (!m_EditingContours.empty()) std::for_each(m_EditingContours.begin(), m_EditingContours.end(), RemoveFromDataStorage(dataStorage)); if (!m_WorkingContours.empty()) std::for_each(m_WorkingContours.begin(), m_WorkingContours.end(), RemoveFromDataStorage(dataStorage)); if (m_EditingContourNode.IsNotNull()) dataStorage->Remove(m_EditingContourNode); if (m_LiveWireContourNode.IsNotNull()) dataStorage->Remove(m_LiveWireContourNode); if (m_ContourModelNode.IsNotNull()) dataStorage->Remove(m_ContourModelNode); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::LiveWireTool2D::ReleaseHelperObjects() { this->RemoveHelperObjects(); if (!m_EditingContours.empty()) m_EditingContours.clear(); if (!m_WorkingContours.empty()) m_WorkingContours.clear(); m_EditingContourNode = NULL; m_EditingContour = NULL; m_LiveWireContourNode = NULL; m_LiveWireContour = NULL; m_ContourModelNode = NULL; m_Contour = NULL; } void mitk::LiveWireTool2D::ReleaseInteractors() { this->EnableContourLiveWireInteraction(false); m_LiveWireInteractors.clear(); } void mitk::LiveWireTool2D::ConnectActionsAndFunctions() { CONNECT_CONDITION("CheckContourClosed", OnCheckPoint); CONNECT_FUNCTION("InitObject", OnInitLiveWire); CONNECT_FUNCTION("AddPoint", OnAddPoint); CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint); CONNECT_FUNCTION("MovePoint", OnMouseMoveNoDynamicCosts); CONNECT_FUNCTION("FinishContour", OnFinish); CONNECT_FUNCTION("DeletePoint", OnLastSegmentDelete); CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved); } const char** mitk::LiveWireTool2D::GetXPM() const { return mitkLiveWireTool2D_xpm; } us::ModuleResource mitk::LiveWireTool2D::GetIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_48x48.png"); } us::ModuleResource mitk::LiveWireTool2D::GetCursorIconResource() const { return us::GetModuleContext()->GetModule()->GetResource("LiveWire_Cursor_32x32.png"); } const char* mitk::LiveWireTool2D::GetName() const { return "Live Wire"; } void mitk::LiveWireTool2D::Activated() { Superclass::Activated(); this->ResetToStartState(); this->EnableContourLiveWireInteraction(true); } void mitk::LiveWireTool2D::Deactivated() { Superclass::Deactivated(); this->ConfirmSegmentation(); } void mitk::LiveWireTool2D::EnableContourLiveWireInteraction(bool on) { std::for_each(m_LiveWireInteractors.begin(), m_LiveWireInteractors.end(), on ? AddInteractorToGlobalInteraction : RemoveInteractorFromGlobalInteraction); } void mitk::LiveWireTool2D::ConfirmSegmentation() { DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); if (!workingNode) return; Image* workingImage = dynamic_cast(workingNode->GetData()); if (!workingImage) return; // for all contours in list (currently created by tool) std::vector< std::pair >::iterator itWorkingContours = this->m_WorkingContours.begin(); while(itWorkingContours != this->m_WorkingContours.end() ) { // if node contains data if( itWorkingContours->first->GetData() ) { // if this is a contourModel mitk::ContourModel* contourModel = dynamic_cast(itWorkingContours->first->GetData()); if( contourModel ) { // for each timestep of this contourModel for( TimeStepType currentTimestep = 0; currentTimestep < contourModel->GetTimeGeometry()->CountTimeSteps(); ++currentTimestep) { //get the segmentation image slice at current timestep mitk::Image::Pointer workingSlice = this->GetAffectedImageSliceAs2DImage(itWorkingContours->second, workingImage, currentTimestep); mitk::ContourModel::Pointer projectedContour = mitk::ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contourModel, true, false); mitk::ContourModelUtils::FillContourInSlice(projectedContour, workingSlice, 1.0); //write back to image volume this->WriteBackSegmentationResult(itWorkingContours->second, workingSlice, currentTimestep); } } } ++itWorkingContours; } this->ReleaseHelperObjects(); this->ReleaseInteractors(); } void mitk::LiveWireTool2D::ClearSegmentation() { this->ReleaseHelperObjects(); this->ReleaseInteractors(); this->ResetToStartState(); } bool mitk::LiveWireTool2D::OnInitLiveWire ( StateMachineAction*, InteractionEvent* interactionEvent ) { mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; m_LastEventSender = positionEvent->GetSender(); m_LastEventSlice = m_LastEventSender->GetSlice(); int timestep = positionEvent->GetSender()->GetTimeStep(); m_Contour = mitk::ContourModel::New(); m_Contour->Expand(timestep+1); m_ContourModelNode = mitk::DataNode::New(); m_ContourModelNode->SetData( m_Contour ); m_ContourModelNode->SetName("working contour node"); m_ContourModelNode->SetProperty( "layer", IntProperty::New(100)); m_ContourModelNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_ContourModelNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); m_ContourModelNode->AddProperty( "contour.color", ColorProperty::New(1, 1, 0), NULL, true ); m_ContourModelNode->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), NULL, true ); m_ContourModelNode->AddProperty( "contour.controlpoints.show", BoolProperty::New(true), NULL, true ); m_LiveWireContour = mitk::ContourModel::New(); m_LiveWireContour->Expand(timestep+1); m_LiveWireContourNode = mitk::DataNode::New(); m_LiveWireContourNode->SetData( m_LiveWireContour ); m_LiveWireContourNode->SetName("active livewire node"); m_LiveWireContourNode->SetProperty( "layer", IntProperty::New(101)); m_LiveWireContourNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_LiveWireContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); - m_LiveWireContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true ); + m_LiveWireContourNode->SetProperty( "color", ColorProperty::New(0.1, 1.0, 0.1)); m_LiveWireContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true ); m_EditingContour = mitk::ContourModel::New(); m_EditingContour->Expand(timestep+1); m_EditingContourNode = mitk::DataNode::New(); m_EditingContourNode->SetData( m_EditingContour ); m_EditingContourNode->SetName("editing node"); m_EditingContourNode->SetProperty( "layer", IntProperty::New(102)); m_EditingContourNode->AddProperty( "fixedLayer", BoolProperty::New(true)); m_EditingContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true)); - m_EditingContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true ); + m_EditingContourNode->SetProperty( "color", ColorProperty::New(0.1, 1.0, 0.1)); m_EditingContourNode->AddProperty( "contour.points.color", ColorProperty::New(0.0, 0.0, 1.0), NULL, true ); m_EditingContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true ); mitk::DataNode* workingDataNode = m_ToolManager->GetWorkingData(0); m_ToolManager->GetDataStorage()->Add(m_ContourModelNode, workingDataNode); m_ToolManager->GetDataStorage()->Add(m_LiveWireContourNode, workingDataNode); m_ToolManager->GetDataStorage()->Add(m_EditingContourNode, workingDataNode); //set current slice as input for ImageToLiveWireContourFilter m_WorkingSlice = this->GetAffectedReferenceSlice(positionEvent); //Transfer LiveWire's center based contour output to corner based via the adaption of the input //slice image. Just in case someone stumbles across the 0.5 here I know what I'm doing ;-). m_WorkingSlice->GetSlicedGeometry()->ChangeImageGeometryConsideringOriginOffset(false); mitk::Point3D newOrigin = m_WorkingSlice->GetSlicedGeometry()->GetOrigin(); m_WorkingSlice->GetSlicedGeometry()->WorldToIndex(newOrigin, newOrigin); newOrigin[2] += 0.5; m_WorkingSlice->GetSlicedGeometry()->IndexToWorld(newOrigin, newOrigin); m_WorkingSlice->GetSlicedGeometry()->SetOrigin(newOrigin); m_LiveWireFilter = mitk::ImageLiveWireContourModelFilter::New(); m_LiveWireFilter->SetInput(m_WorkingSlice); //map click to pixel coordinates mitk::Point3D click = positionEvent->GetPositionInWorld(); itk::Index<3> idx; m_WorkingSlice->GetGeometry()->WorldToIndex(click, idx); // get the pixel the gradient in region of 5x5 itk::Index<3> indexWithHighestGradient; AccessFixedDimensionByItk_2(m_WorkingSlice, FindHighestGradientMagnitudeByITK, 2, idx, indexWithHighestGradient); // itk::Index to mitk::Point3D click[0] = indexWithHighestGradient[0]; click[1] = indexWithHighestGradient[1]; click[2] = indexWithHighestGradient[2]; m_WorkingSlice->GetGeometry()->IndexToWorld(click, click); //set initial start point m_Contour->AddVertex( click, true, timestep ); m_LiveWireFilter->SetStartPoint(click); m_CreateAndUseDynamicCosts = true; //render assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnAddPoint ( StateMachineAction*, InteractionEvent* interactionEvent ) { //complete LiveWire interaction for last segment //add current LiveWire contour to the finished contour and reset //to start new segment and computation /* check if event can be handled */ mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; int timestep = positionEvent->GetSender()->GetTimeStep(); //add repulsive points to avoid to get the same path again typedef mitk::ImageLiveWireContourModelFilter::InternalImageType::IndexType IndexType; mitk::ContourModel::ConstVertexIterator iter = m_LiveWireContour->IteratorBegin(timestep); for (;iter != m_LiveWireContour->IteratorEnd(timestep); iter++) { IndexType idx; this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx); this->m_LiveWireFilter->AddRepulsivePoint( idx ); } //remove duplicate first vertex, it's already contained in m_Contour m_LiveWireContour->RemoveVertexAt(0, timestep); // set last added point as control point m_LiveWireContour->SetControlVertexAt(m_LiveWireContour->GetNumberOfVertices(timestep)-1, timestep); //merge contours m_Contour->Concatenate(m_LiveWireContour, timestep); //clear the livewire contour and reset the corresponding datanode m_LiveWireContour->Clear(timestep); //set new start point m_LiveWireFilter->SetStartPoint(positionEvent->GetPositionInWorld()); if( m_CreateAndUseDynamicCosts ) { //use dynamic cost map for next update m_LiveWireFilter->CreateDynamicCostMap(m_Contour); m_LiveWireFilter->SetUseDynamicCostMap(true); //m_CreateAndUseDynamicCosts = false; } //render assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent ) { //compute LiveWire segment from last control point to current mouse position mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; // actual LiveWire computation int timestep = positionEvent->GetSender()->GetTimeStep(); m_LiveWireFilter->SetEndPoint(positionEvent->GetPositionInWorld()); m_LiveWireFilter->SetTimeStep( timestep ); m_LiveWireFilter->Update(); m_LiveWireContour = this->m_LiveWireFilter->GetOutput(); m_LiveWireContourNode->SetData( this->m_LiveWireContour ); //render assert( positionEvent->GetSender()->GetRenderWindow() ); positionEvent->GetSender()->GetRenderingManager()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); return true; } bool mitk::LiveWireTool2D::OnMouseMoveNoDynamicCosts( StateMachineAction*, InteractionEvent* interactionEvent ) { //do not use dynamic cost map m_LiveWireFilter->SetUseDynamicCostMap(false); OnMouseMoved( NULL, interactionEvent); m_LiveWireFilter->SetUseDynamicCostMap(true); return true; } bool mitk::LiveWireTool2D::OnCheckPoint( const InteractionEvent* interactionEvent) { //check double click on first control point to finish the LiveWire tool // //Check distance to first point. //Transition YES if click close to first control point // const mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (positionEvent) { int timestep = positionEvent->GetSender()->GetTimeStep(); mitk::Point3D click = positionEvent->GetPositionInWorld(); mitk::Point3D first = this->m_Contour->GetVertexAt(0, timestep)->Coordinates; if (first.EuclideanDistanceTo(click) < 4.5) { // allow to finish return true; } else { return false; } } return false; } bool mitk::LiveWireTool2D::OnFinish( StateMachineAction*, InteractionEvent* interactionEvent ) { // finish livewire tool interaction mitk::InteractionPositionEvent* positionEvent = dynamic_cast( interactionEvent ); if (!positionEvent) return false; // actual timestep int timestep = positionEvent->GetSender()->GetTimeStep(); // remove last control point being added by double click m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices(timestep) - 1, timestep); // save contour and corresponding plane geometry to list std::pair cp(m_ContourModelNode, dynamic_cast(positionEvent->GetSender()->GetCurrentWorldGeometry2D()->Clone().GetPointer()) ); this->m_WorkingContours.push_back(cp); std::pair ecp(m_EditingContourNode, dynamic_cast(positionEvent->GetSender()->GetCurrentWorldGeometry2D()->Clone().GetPointer()) ); this->m_EditingContours.push_back(ecp); m_LiveWireFilter->SetUseDynamicCostMap(false); this->FinishTool(); return true; } void mitk::LiveWireTool2D::FinishTool() { TimeStepType numberOfTimesteps = m_Contour->GetTimeGeometry()->CountTimeSteps(); //close contour in each timestep for( int i = 0; i <= numberOfTimesteps; i++) { m_Contour->Close(i); } m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode ); // clear live wire contour node m_LiveWireContourNode = NULL; m_LiveWireContour = NULL; //set the livewire interactor to edit control points m_ContourInteractor = mitk::ContourModelLiveWireInteractor::New(m_ContourModelNode); m_ContourInteractor->SetWorkingImage(this->m_WorkingSlice); m_ContourInteractor->SetEditingContourModelNode(this->m_EditingContourNode); m_ContourModelNode->SetInteractor(m_ContourInteractor); this->m_LiveWireInteractors.push_back( m_ContourInteractor ); //add interactor to globalInteraction instance mitk::GlobalInteraction::GetInstance()->AddInteractor(m_ContourInteractor); } bool mitk::LiveWireTool2D::OnLastSegmentDelete( StateMachineAction*, InteractionEvent* interactionEvent ) { int timestep = interactionEvent->GetSender()->GetTimeStep(); //if last point of current contour will be removed go to start state and remove nodes if( m_Contour->GetNumberOfVertices(timestep) <= 1 ) { m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode ); m_ToolManager->GetDataStorage()->Remove( m_ContourModelNode ); m_ToolManager->GetDataStorage()->Remove( m_EditingContourNode ); m_LiveWireContour = mitk::ContourModel::New(); m_Contour = mitk::ContourModel::New(); m_ContourModelNode->SetData( m_Contour ); m_LiveWireContourNode->SetData( m_LiveWireContour ); this->ResetToStartState(); //go to start state } else //remove last segment from contour and reset livewire contour { m_LiveWireContour = mitk::ContourModel::New(); m_LiveWireContourNode->SetData(m_LiveWireContour); mitk::ContourModel::Pointer newContour = mitk::ContourModel::New(); newContour->Expand(m_Contour->GetTimeSteps()); mitk::ContourModel::VertexIterator begin = m_Contour->IteratorBegin(); //iterate from last point to next active point mitk::ContourModel::VertexIterator newLast = m_Contour->IteratorBegin() + (m_Contour->GetNumberOfVertices() - 1); //go at least one down if(newLast != begin) { newLast--; } //search next active control point while(newLast != begin && !((*newLast)->IsControlPoint) ) { newLast--; } //set position of start point for livewire filter to coordinates of the new last point m_LiveWireFilter->SetStartPoint((*newLast)->Coordinates); mitk::ContourModel::VertexIterator it = m_Contour->IteratorBegin(); //fill new Contour while(it <= newLast) { newContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep); it++; } newContour->SetClosed(m_Contour->IsClosed()); //set new contour visible m_ContourModelNode->SetData(newContour); m_Contour = newContour; assert( interactionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( interactionEvent->GetSender()->GetRenderWindow() ); } return true; } template void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image* inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; unsigned long xMAX = inputImage->GetLargestPossibleRegion().GetSize()[0]; unsigned long yMAX = inputImage->GetLargestPossibleRegion().GetSize()[1]; returnIndex[0] = index[0]; returnIndex[1] = index[1]; returnIndex[2] = 0.0; double gradientMagnitude = 0.0; double maxGradientMagnitude = 0.0; /* the size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region not for searching the maximum value */ //maximum value in each direction for size typename InputImageType::SizeType size; size[0] = 7; size[1] = 7; //minimum value in each direction for startRegion IndexType startRegion; startRegion[0] = index[0] - 3; startRegion[1] = index[1] - 3; if(startRegion[0] < 0) startRegion[0] = 0; if(startRegion[1] < 0) startRegion[1] = 0; if(xMAX - index[0] < 7) startRegion[0] = xMAX - 7; if(yMAX - index[1] < 7) startRegion[1] = yMAX - 7; index[0] = startRegion[0] + 3; index[1] = startRegion[1] + 3; typename InputImageType::RegionType region; region.SetSize( size ); region.SetIndex( startRegion ); typedef typename itk::GradientMagnitudeImageFilter< InputImageType, InputImageType> GradientMagnitudeFilterType; typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New(); gradientFilter->SetInput(inputImage); gradientFilter->GetOutput()->SetRequestedRegion(region); gradientFilter->Update(); typename InputImageType::Pointer gradientMagnImage; gradientMagnImage = gradientFilter->GetOutput(); IndexType currentIndex; currentIndex[0] = 0; currentIndex[1] = 0; // search max (approximate) gradient magnitude for( int x = -1; x <= 1; ++x) { currentIndex[0] = index[0] + x; for( int y = -1; y <= 1; ++y) { currentIndex[1] = index[1] + y; gradientMagnitude = gradientMagnImage->GetPixel(currentIndex); //check for new max if(maxGradientMagnitude < gradientMagnitude) { maxGradientMagnitude = gradientMagnitude; returnIndex[0] = currentIndex[0]; returnIndex[1] = currentIndex[1]; returnIndex[2] = 0.0; }//end if }//end for y currentIndex[1] = index[1]; }//end for x } diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 6abfe68531..7f4439d785 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,57 +1,58 @@ # Plug-ins must be ordered according to their dependencies if (MITK_USE_Qt4) set(MITK_EXT_PLUGINS 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.rt.dosevisualization:ON 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.diffusionimaging:OFF org.mitk.gui.qt.dtiatlasapp:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON 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.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.toftutorial:OFF org.mitk.gui.qt.tofutil: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 ) else() set(MITK_EXT_PLUGINS # empty so far ) endif() diff --git a/Plugins/org.mitk.dicomrtview/src/internal/DcmRTV.cpp b/Plugins/org.mitk.dicomrtview/src/internal/DcmRTV.cpp new file mode 100644 index 0000000000..7ce5bf0885 --- /dev/null +++ b/Plugins/org.mitk.dicomrtview/src/internal/DcmRTV.cpp @@ -0,0 +1,478 @@ +/*=================================================================== + +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. + +===================================================================*/ + + +// Blueberry +#include +#include + +// Qmitk +#include "DcmRTV.h" + +#include +#include +#include + +#include "mitkSegmentationObjectFactory.h" + + +// Qt +#include + + +const std::string DcmRTV::VIEW_ID = "org.mitk.views.dcmrtv"; + +DcmRTV::DcmRTV() +{ + mitk::IsoDoseLevel::ColorType color; + color[0] = 1.0; + color[1] = 1.0; + color[2] = 1.0; + m_freeIsoValues = mitk::IsoDoseLevelVector::New(); + m_freeIsoValues->push_back(mitk::IsoDoseLevel::New(0.0,color,true,false)); + + // std::string m_VolumeDir = MITK_ROOT; + // m_VolumeDir += "../mbi/Plugins/org.mbi.gui.qt.tofoscopy"; + // mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( m_VolumeDir.c_str(), false ); + // mitk::ShaderRepository::Pointer shaderRepository = mitk::ShaderRepository::GetGlobalShaderRepository(); + mitk::CoreServicePointer shadoRepo(mitk::CoreServices::GetShaderRepository()); + + std::string path = "/home/riecker/mitkShaderLighting.xml"; //mitk::StandardFileLocations::GetInstance()->FindFile("mitkShaderTOF.xml"); + std::string isoShaderName = "mitkIsoLineShader"; + MITK_INFO << "shader found under: " << path; + std::ifstream str(path.c_str()); + shadoRepo->LoadShader(str,isoShaderName); +} + +DcmRTV::~DcmRTV(){} + +void DcmRTV::SetFocus() +{ + m_Controls.buttonPerformImageProcessing->setFocus(); +} + +void DcmRTV::CreateQtPartControl( QWidget *parent ) +{ + RegisterSegmentationObjectFactory(); + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi( parent ); + connect( m_Controls.buttonPerformImageProcessing, SIGNAL(clicked()), this, SLOT(DoImageProcessing()) ); + connect( m_Controls.pushButton, SIGNAL(clicked()), this, SLOT(LoadRTDoseFile()) ); + connect( m_Controls.btn_isolines, SIGNAL(clicked()), this ,SLOT(LoadIsoLines())); + + connect(m_Controls.btnUpdate, SIGNAL(clicked()), this, SLOT(OnUpdateButtonClicked())); + connect(m_Controls.freeSlider, SIGNAL(valueChanged(int)), m_Controls.freeBox, SLOT(setValue(int))); + connect(m_Controls.freeBox, SIGNAL(valueChanged(int)), this, SLOT(OnFreeIsoValueChanged(int))); + connect(m_Controls.spinPrescribedDose, SIGNAL(valueChanged(double)), this, SLOT(OnPrescribedDoseChanged(double))); +} + +void DcmRTV::OnPrescribedDoseChanged(double value) +{ + if (m_selectedNode.IsNotNull()) + { + m_selectedNode->SetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(), m_Controls.spinPrescribedDose->value()); + } +} + +void DcmRTV::LoadIsoLines() +{ + bool result; + if(m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),result) && result) + { + m_selectedNode->SetProperty("shader",mitk::ShaderProperty::New("mitkIsoLineShader")); + m_selectedNode->SetProperty("shader.mitkIsoLineShader.CustomISO", mitk::FloatProperty::New(20)); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + else + { + MITK_WARN << "Selected file has to be a Dose file!"; + } +} + +//void DcmRTV::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, +// const QList& nodes ) +//{ +// // iterate all selected objects, adjust warning visibility +// foreach( mitk::DataNode::Pointer node, nodes ) +// { +// if( node.IsNotNull() && dynamic_cast(node->GetData()) ) +// { +// m_Controls.buttonPerformImageProcessing->setEnabled( true ); +// return; +// } +// } + +// m_Controls.buttonPerformImageProcessing->setEnabled( true ); +//} + +void DcmRTV::OnFreeIsoValueChanged(int value) +{ + if(m_selectedNode.IsNotNull()) + { + m_selectedNode->SetProperty("shader.mitkIsoLineShader.CustomISO", mitk::FloatProperty::New(m_Controls.freeBox->value())); + (*m_freeIsoValues)[0]->SetDoseValue(value/100.0); + mitk::IsoDoseLevelVectorProperty::Pointer levelVecProp = mitk::IsoDoseLevelVectorProperty::New(m_freeIsoValues); + m_selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),levelVecProp); + + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + } +} + +void DcmRTV::OnUpdateButtonClicked() +{ + if(m_selectedNode.IsNotNull()) + { + m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), true); + m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(), true); + m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME.c_str(), true); + m_selectedNode->SetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(), m_Controls.spinPrescribedDose->value()); + + mitk::IsoDoseLevelSet::Pointer levelSet = mitk::IsoDoseLevelSet::New(); + + mitk::IsoDoseLevel::ColorType color; + color[0] = 0.0; + color[1] = 0.0; + color[2] = 0.4; + mitk::IsoDoseLevel::Pointer level = mitk::IsoDoseLevel::New(0.01,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.2; + color[2] = 0.8; + level = mitk::IsoDoseLevel::New(0.1,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.4; + color[2] = 1.0; + level = mitk::IsoDoseLevel::New(0.2,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.7; + color[2] = 1.0; + level = mitk::IsoDoseLevel::New(0.3,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 0.7; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(0.4,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.0; + color[1] = 1.0; + color[2] = 0.3; + level = mitk::IsoDoseLevel::New(0.5,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 1.0; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(0.6,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 1.0; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.7,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.8; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.8,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.5; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.9,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.4; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(0.95,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.2; + color[2] = 0.0; + level = mitk::IsoDoseLevel::New(1.0,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.0; + color[2] = 0.3; + level = mitk::IsoDoseLevel::New(1.07,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.0; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.1,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.4; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.2,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 1.0; + color[1] = 0.7; + color[2] = 0.7; + level = mitk::IsoDoseLevel::New(1.3,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.8; + color[1] = 0.6; + color[2] = 0.6; + level = mitk::IsoDoseLevel::New(1.4,color,true,true); + levelSet->SetIsoDoseLevel(level); + + color[0] = 0.65; + color[1] = 0.4; + color[2] = 0.4; + level = mitk::IsoDoseLevel::New(1.5,color,true,true); + levelSet->SetIsoDoseLevel(level); + + mitk::IsoDoseLevelSetProperty::Pointer levelSetProp = mitk::IsoDoseLevelSetProperty::New(levelSet); + m_selectedNode->SetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),levelSetProp); + + + (*m_freeIsoValues)[0]->SetDoseValue(m_Controls.freeBox->value()/100.0); + mitk::IsoDoseLevelVectorProperty::Pointer levelVecProp = mitk::IsoDoseLevelVectorProperty::New(m_freeIsoValues); + m_selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),levelVecProp); + + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + } +} + +void DcmRTV::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes ) +{ + QList dataNodes = this->GetDataManagerSelection(); + if (dataNodes.empty()) + { + m_selectedNode = NULL; + m_Controls.btn_isolines->setDisabled(true); + } + else + { + m_selectedNode = dataNodes[0]; + bool result; + if(m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),result) && result) + { + m_Controls.btn_isolines->setEnabled(m_selectedNode.IsNotNull()); + } + else + { + m_Controls.btn_isolines->setDisabled(true); + } + } + m_Controls.btnUpdate->setEnabled(m_selectedNode.IsNotNull()); +// m_Controls.btn_isolines->setEnabled(m_selectedNode.IsNotNull()); +} + +void DcmRTV::UpdateIsoLines(int value) +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.dcm")); + + mitk::DicomSeriesReader::StringContainer files; + QStringList fileNames = dialog.getOpenFileNames(); + if(fileNames.empty()) + { + return; + } + QStringListIterator fileNamesIterator(fileNames); + while(fileNamesIterator.hasNext()) + { + files.push_back(fileNamesIterator.next().toStdString()); + } + + std::string tmp = files.front(); + const char* filename = tmp.c_str(); + char* ncFilename = const_cast(filename); + + mitk::DicomRTReader::Pointer _DicomRTReader = mitk::DicomRTReader::New(); + + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.bad()) + { + QMessageBox::information(NULL,"Error","Cant read the file"); + } + DcmDataset *dataset = file.getDataset(); + + mitk::DataNode::Pointer mitkImage = mitk::DataNode::New(); + mitkImage = _DicomRTReader->LoadRTDose(dataset,ncFilename); + + mitk::Image::Pointer picture = dynamic_cast(mitkImage->GetData()); + + vtkSmartPointer polyData = vtkSmartPointer::New(); + double omg = value; + polyData = _DicomRTReader->GetIsoLine(omg, picture->GetVtkImageData()); + mitk::Surface::Pointer surface = mitk::Surface::New(); + surface->SetVtkPolyData(polyData); + for(int i=0;iGetLength();++i) + { + double* ar; + polyData->GetPoint(i,ar); + } + + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(surface); + GetDataStorage()->Add(node); +} + +void DcmRTV::DoImageProcessing() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.dcm")); + + mitk::DicomSeriesReader::StringContainer files; + QStringList fileNames = dialog.getOpenFileNames(); + if(fileNames.empty()) + { + return; + } + QStringListIterator fileNamesIterator(fileNames); + while(fileNamesIterator.hasNext()) + { + files.push_back(fileNamesIterator.next().toStdString()); + } + + std::string tmp = files.front(); + const char* filename = tmp.c_str(); + char* filenameC = const_cast(filename); + + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.bad()) + { + QMessageBox::information(NULL,"Error","Cant read the file"); + } + DcmDataset *dataset = file.getDataset(); + + mitk::DicomRTReader::Pointer readerRT = mitk::DicomRTReader::New(); + std::deque modelVector; + modelVector = readerRT->ReadDicomFile(filenameC); + + if(modelVector.empty()) + { + QMessageBox::information(NULL, "Error", "Vector is empty ..."); + } + + for(int i=0; iSetData(modelVector.at(i)); + x->SetProperty("name", modelVector.at(i)->GetProperty("name")); + x->SetVisibility(true); + GetDataStorage()->Add(x); + } + mitk::TimeSlicedGeometry::Pointer geo = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); + mitk::RenderingManager::GetInstance()->InitializeViews( geo ); +} + +void DcmRTV::LoadRTDoseFile() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.dcm")); + + mitk::DicomSeriesReader::StringContainer files; + QStringList fileNames = dialog.getOpenFileNames(); + if(fileNames.empty()) + { + return; + } + QStringListIterator fileNamesIterator(fileNames); + while(fileNamesIterator.hasNext()) + { + files.push_back(fileNamesIterator.next().toStdString()); + } + + std::string tmp = files.front(); + const char* filename = tmp.c_str(); + char* ncFilename = const_cast(filename); + + mitk::DicomRTReader::Pointer _DicomRTReader = mitk::DicomRTReader::New(); + + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.bad()) + { + QMessageBox::information(NULL,"Error","Cant read the file"); + } + DcmDataset *dataset = file.getDataset(); + + mitk::DataNode::Pointer mitkImage = mitk::DataNode::New(); + mitkImage = _DicomRTReader->LoadRTDose(dataset,ncFilename); + + GetDataStorage()->Add(mitkImage); + +// mitk::DataNode::Pointer doseNode = GetDataStorage()->GetNamedNode("DicomRT Dose"); +// mitk::Image::Pointer doseImage = dynamic_cast(doseNode->GetData()); +// vtkMarchingSquares* contourFilter = vtkMarchingSquares::New(); +// std::deque surfaceStorage; + +// mitk::ExtractImageFilter::Pointer imageExtractor = mitk::ExtractImageFilter::New(); +// mitk::DataNode::Pointer img = this->GetDataStorage()->GetNamedNode("abc"); +// mitk::Image::Pointer picture = dynamic_cast(img->GetData()); +// imageExtractor->SetInput( picture ); +// imageExtractor->SetSliceDimension( 2 ); +// imageExtractor->SetSliceIndex( 12 ); +// imageExtractor->Update(); + +// vtkMarchingSquares* contourFilter = vtkMarchingSquares::New(); +// vtkPolyData* polyData = vtkPolyData::New(); + +// contourFilter->SetInput(imageExtractor->GetOutput()->GetVtkImageData()); +// contourFilter->SetNumberOfContours(1); +// contourFilter->SetValue(0,0.5); +// polyData = contourFilter->GetOutput(); + +// mitk::Surface::Pointer c = mitk::Surface::New(); +// c->SetVtkPolyData(polyData); +// mitk::Geometry3D::Pointer geo = doseImage->GetGeometry()->Clone(); +// mitk::Vector3D spacing; +// spacing.Fill(1); +// geo->SetSpacing(spacing); +// surfaceStorage.push_back(c); + +// mitk::DataNode::Pointer extractNode = mitk::DataNode::New(); +// mitk::Image::Pointer stuff = dynamic_cast(imageExtractor->GetOutput()); +// mitk::Geometry3D::Pointer geo2 = stuff->GetGeometry()->Clone(); +// mitk::Vector3D spacing2; +// spacing2.Fill(1); +// geo2->SetSpacing(spacing2); +// stuff->SetGeometry(geo); +// extractNode->SetData(stuff); +// extractNode->SetName("ExtractImage"); +// GetDataStorage()->Add(extractNode); + +// mitk::DataNode::Pointer contourNode = mitk::DataNode::New(); +// c->SetGeometry(geo2); +// contourNode->SetData(c); +// contourNode->SetName("IsoDose"); +// GetDataStorage()->Add(contourNode); + + mitk::TimeSlicedGeometry::Pointer geo3 = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); + mitk::RenderingManager::GetInstance()->InitializeViews( geo3 ); +} diff --git a/Plugins/org.mitk.dicomrtview/src/internal/DcmRTVControls.ui b/Plugins/org.mitk.dicomrtview/src/internal/DcmRTVControls.ui new file mode 100644 index 0000000000..c8ee7e424b --- /dev/null +++ b/Plugins/org.mitk.dicomrtview/src/internal/DcmRTVControls.ui @@ -0,0 +1,201 @@ + + + DcmRTVControls + + + + 0 + 0 + 244 + 329 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + + 204 + 0 + + + + + 31 + 75 + true + true + + + + Qt::LeftToRight + + + DICOM RT + + + Qt::AlignCenter + + + + + + + + 0 + 30 + + + + Do image processing + + + Load Structure Set + + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + Load Dose File + + + + + + + + + Isolines + + + + + + + Qt::Horizontal + + + + 40 + 40 + + + + + + + + + + + 0 + 0 + + + + Qt::NoFocus + + + Prescribed dose [Gy] + + + + + + + 1 + + + + + + + + + Update iso level + + + + + + + + + Free Iso Dose [%] + + + + + + + 50 + + + 20 + + + 20 + + + Qt::Horizontal + + + + + + + 50 + + + 20 + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/CMakeLists.txt b/Plugins/org.mitk.gui.qt.rt.dosevisualization/CMakeLists.txt new file mode 100644 index 0000000000..243c436059 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_rt_dosevisualization) + +MACRO_CREATE_MITK_CTK_PLUGIN( + EXPORT_DIRECTIVE RTDOSEVISUALIZATION_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkDicomRT MitkRTUI +) diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..8b68f8e2c8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/Manual.dox @@ -0,0 +1,18 @@ +/** +\page org_mitk_dicomrtview Dicomrtview + +\image html icon.xpm "Icon of Dicomrtview" + +Available sections: + - \ref org_mitk_dicomrtviewOverview + +\section org_mitk_dicomrtviewOverview +Describe the features of your awesome plugin here +
    +
  • Increases productivity +
  • Creates beautiful images +
  • Generates PhD thesis +
  • Brings world peace +
+ +*/ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/icon.xpm b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/icon.xpm new file mode 100644 index 0000000000..83e48be4d8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/UserManual/icon.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * icon_xpm[] = { +"16 16 2 1", +" c #FF0000", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..bfe7d676e2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_dicomrtview org.mitk.dicomrtview + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_dicomrtview_internal Internal + \ingroup org_mitk_dicomrtview + + \brief This subcategory includes the internal classes of the org.mitk.dicomrtview plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/files.cmake b/Plugins/org.mitk.gui.qt.rt.dosevisualization/files.cmake new file mode 100644 index 0000000000..3acb2dbbb9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/files.cmake @@ -0,0 +1,55 @@ +set(SRC_CPP_FILES +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_rt_dosevisualization_Activator.cpp + RTDoseVisualizer.cpp + RTUIPreferencePage.cpp + DoseVisualizationPreferencePage.cpp + mitkDoseVisPreferenceHelper.cpp + LoadingRTView.cpp +) + +set(UI_FILES + src/internal/RTDoseVisualizerControls.ui + src/internal/DoseVisualizationPreferencePageControls.ui + src/internal/RTUIPreferencePageControls.ui + src/internal/LoadingRTViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.h + src/internal/RTDoseVisualizer.h + src/internal/RTUIPreferencePage.h + src/internal/DoseVisualizationPreferencePage.h + src/internal/LoadingRTView.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/iso.png + resources/iso2.png + resources/icon4.png + resources/icon5.png + resources/icon7.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +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.rt.dosevisualization/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.rt.dosevisualization/manifest_headers.cmake new file mode 100644 index 0000000000..9492c2783b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "RTDoseVisualization") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Software development for Integrated Diagnostic and Therapy") +set(Plugin-ContactAddress "sbr@dkfz-heidelber.de") +set(Require-Plugin org.mitk.gui.qt.common org.commontk.eventadmin) diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/plugin.xml b/Plugins/org.mitk.gui.qt.rt.dosevisualization/plugin.xml new file mode 100644 index 0000000000..7ad988c76e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/plugin.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon4.png b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon4.png new file mode 100644 index 0000000000..07e3d5d412 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon4.png differ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon5.png b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon5.png new file mode 100644 index 0000000000..a3338ef126 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon5.png differ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon7.png b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon7.png new file mode 100644 index 0000000000..55f6b4cbf3 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/icon7.png differ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso.png b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso.png new file mode 100644 index 0000000000..7edf418042 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso.png differ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso2.png b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso2.png new file mode 100644 index 0000000000..2a73d321db Binary files /dev/null and b/Plugins/org.mitk.gui.qt.rt.dosevisualization/resources/iso2.png differ diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.cpp new file mode 100644 index 0000000000..e5e934987f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.cpp @@ -0,0 +1,377 @@ +/*=================================================================== + +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 "DoseVisualizationPreferencePage.h" +#include "mitkRTUIConstants.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "mitkIsoLevelsGenerator.h" + +#include "org_mitk_gui_qt_rt_dosevisualization_Activator.h" + +DoseVisualizationPreferencePage::DoseVisualizationPreferencePage() + : m_MainControl(0), m_Controls(0), m_referenceDoseChanged(false), m_presetMapChanged(false) +{ + +} + +DoseVisualizationPreferencePage::~DoseVisualizationPreferencePage() +{ + delete m_LevelSetModel; + delete m_DoseColorDelegate; + delete m_DoseValueDelegate; + delete m_DoseVisualDelegate; + delete m_Controls; +} + +void DoseVisualizationPreferencePage::Init(berry::IWorkbench::Pointer ) +{ + +} + +void DoseVisualizationPreferencePage::CreateQtControl(QWidget* parent) +{ + berry::IPreferencesService::Pointer prefService + = berry::Platform::GetServiceRegistry() + .GetServiceById(berry::IPreferencesService::ID); + + m_DoseVisNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + m_MainControl = new QWidget(parent); + m_Controls = new Ui::DoseVisualizationPreferencePageControls; + m_Controls->setupUi( m_MainControl ); + + m_LevelSetModel = new QmitkIsoDoseLevelSetModel(this); + m_DoseColorDelegate = new QmitkDoseColorDelegate(this); + m_DoseValueDelegate = new QmitkDoseValueDelegate(this); + m_DoseVisualDelegate = new QmitkDoseVisualStyleDelegate(this); + + this->m_Controls->isoLevelSetView->setModel(m_LevelSetModel); + this->m_Controls->isoLevelSetView->setItemDelegateForColumn(0,m_DoseColorDelegate); + this->m_Controls->isoLevelSetView->setItemDelegateForColumn(1,m_DoseValueDelegate); + this->m_Controls->isoLevelSetView->setItemDelegateForColumn(2,m_DoseVisualDelegate); + this->m_Controls->isoLevelSetView->setItemDelegateForColumn(3,m_DoseVisualDelegate); + this->m_Controls->isoLevelSetView->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(m_Controls->spinReferenceDose, SIGNAL(valueChanged(double)), m_LevelSetModel, SLOT(setReferenceDose(double))); + connect(m_Controls->spinReferenceDose, SIGNAL(valueChanged(double)), this, SLOT(OnReferenceDoseChanged(double))); + connect(m_Controls->checkGlobalSync, SIGNAL(toggled(bool)), m_Controls->spinReferenceDose, SLOT(setEnabled(bool))); + connect(m_Controls->radioAbsDose, SIGNAL(toggled(bool)), m_LevelSetModel, SLOT(setShowAbsoluteDose(bool))); + connect(m_Controls->isoLevelSetView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnShowContextMenuIsoSet(const QPoint&))); + connect(m_Controls->listPresets, SIGNAL(currentItemChanged ( QListWidgetItem *, QListWidgetItem *)), this, SLOT(OnCurrentItemChanged ( QListWidgetItem *, QListWidgetItem *))); + connect(m_Controls->btnAddPreset, SIGNAL(clicked(bool)), this, SLOT(OnAddPresetClicked(bool))); + connect(m_Controls->btnDelPreset, SIGNAL(clicked(bool)), this, SLOT(OnDelPresetClicked(bool))); + connect(m_Controls->btnResetPreset, SIGNAL(clicked(bool)), this, SLOT(OnResetPresetClicked(bool))); + connect(m_Controls->btnDelLevel, SIGNAL(clicked(bool)), this, SLOT(OnDelLevelClicked(bool))); + connect(m_Controls->btnAddLevel, SIGNAL(clicked(bool)), this, SLOT(OnAddLevelClicked(bool))); + + this->Update(); +} + +QWidget* DoseVisualizationPreferencePage::GetQtControl() const +{ + return m_MainControl; +} + +bool DoseVisualizationPreferencePage::PerformOk() +{ + m_DoseVisNode->PutBool(mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID,m_Controls->radioAbsDose->isChecked()); + m_DoseVisNode->PutBool(mitk::rt::UIConstants::GLOBAL_VISIBILITY_COLORWASH_ID,m_Controls->checkGlobalVisColorWash->isChecked()); + m_DoseVisNode->PutBool(mitk::rt::UIConstants::GLOBAL_VISIBILITY_ISOLINES_ID,m_Controls->checkGlobalVisIsoLine->isChecked()); + m_DoseVisNode->PutDouble(mitk::rt::UIConstants::REFERENCE_DOSE_ID,m_Controls->spinReferenceDose->value()); + m_DoseVisNode->PutBool(mitk::rt::UIConstants::GLOBAL_REFERENCE_DOSE_SYNC_ID, m_Controls->checkGlobalSync->isChecked()); + + mitk::rt::StorePresetsMap(this->m_Presets); + + if (this->m_Presets.find(this->m_selectedPresetName)==this->m_Presets.end()) + { //the preset currently selected in the application is not available any more. Change it to a valid one. + mitk::rt::SetSelectedPresetName(this->m_Presets.begin()->first); + } + + if (this->m_LevelSetModel->isModified()) + { + this->m_presetMapChanged = true; + } + + if (m_referenceDoseChanged) + { + mitk::rt::SignalReferenceDoseChange(m_Controls->checkGlobalSync->isChecked(), m_Controls->spinReferenceDose->value(), mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()); + } + + if (m_presetMapChanged) + { + mitk::rt::SignalPresetMapChange(mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()); + } + + return true; +} + +void DoseVisualizationPreferencePage::PerformCancel() +{ +} + +void DoseVisualizationPreferencePage::Update() +{ + m_Controls->checkGlobalVisColorWash->setChecked(m_DoseVisNode->GetBool(mitk::rt::UIConstants::GLOBAL_VISIBILITY_COLORWASH_ID, true)); + m_Controls->checkGlobalVisIsoLine->setChecked(m_DoseVisNode->GetBool(mitk::rt::UIConstants::GLOBAL_VISIBILITY_ISOLINES_ID, true)); + m_Controls->radioAbsDose->setChecked(m_DoseVisNode->GetBool(mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID, true)); + m_Controls->radioRelDose->setChecked(!(m_DoseVisNode->GetBool(mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID, false))); + m_Controls->spinReferenceDose->setValue(m_DoseVisNode->GetDouble(mitk::rt::UIConstants::REFERENCE_DOSE_ID, mitk::rt::UIConstants::DEFAULT_REFERENCE_DOSE_VALUE)); + m_Controls->checkGlobalSync->setChecked(m_DoseVisNode->GetBool(mitk::rt::UIConstants::GLOBAL_REFERENCE_DOSE_SYNC_ID, true)); + + m_referenceDoseChanged = false; + m_presetMapChanged = false; + + + berry::IPreferences::Pointer presetsNode = m_DoseVisNode->Node(mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID); + this->m_Presets = mitk::rt::LoadPresetsMap(); + this->m_selectedPresetName = mitk::rt::GetSelectedPresetName(); + UpdatePresetsWidgets(); +} + + +mitk::IsoDoseLevelSet* DoseVisualizationPreferencePage::GetSelectedIsoLevelSet() +{ + QListWidgetItem* selectedItem = m_Controls->listPresets->currentItem(); + + mitk::IsoDoseLevelSet::Pointer result; + + if (selectedItem) + { + result = m_Presets[selectedItem->text().toStdString()]; + } + + return result; +} + +void DoseVisualizationPreferencePage::UpdateLevelSetWidgets() +{ + this->m_Controls->btnAddLevel->setEnabled(this->GetSelectedIsoLevelSet()!=NULL); + + QModelIndex selectedIndex = m_Controls->isoLevelSetView->currentIndex(); + this->m_Controls->btnDelLevel->setEnabled(this->GetSelectedIsoLevelSet()!=NULL && selectedIndex.isValid()); +} + +void DoseVisualizationPreferencePage::UpdatePresetsWidgets() +{ + m_Controls->listPresets->clear(); + + QListWidgetItem* selectedItem = NULL; + for (PresetMapType::iterator pos = m_Presets.begin(); pos != m_Presets.end(); ++pos) + { + QListWidgetItem* item = new QListWidgetItem(QString::fromStdString(pos->first)); + if (!selectedItem) + { + selectedItem = item; + } + + m_Controls->listPresets->addItem(item); + } + + if (selectedItem) + { + m_Controls->listPresets->setCurrentItem(selectedItem); + } + + if (this->m_LevelSetModel->isModified()) + { + this->m_presetMapChanged = true; + } + + this->m_LevelSetModel->setIsoDoseLevelSet(this->GetSelectedIsoLevelSet()); + + m_Controls->btnDelPreset->setEnabled((m_Controls->listPresets->currentItem() != NULL) && (m_Controls->listPresets->count()>1)); +} + +void DoseVisualizationPreferencePage::OnCurrentItemChanged ( QListWidgetItem * currentItem, QListWidgetItem * previousItem) +{ + this->m_LevelSetModel->setIsoDoseLevelSet(this->GetSelectedIsoLevelSet()); +} + +void DoseVisualizationPreferencePage::OnShowContextMenuIsoSet(const QPoint& pos) +{ + QPoint globalPos = m_Controls->isoLevelSetView->viewport()->mapToGlobal(pos); + + QModelIndex selectedIndex = m_Controls->isoLevelSetView->currentIndex(); + + QMenu viewMenu; + QAction* addLevelAct = viewMenu.addAction("Add new level"); + QAction* delLevelAct = viewMenu.addAction("Delete selected level"); + delLevelAct->setEnabled(selectedIndex.isValid()); + viewMenu.addSeparator(); + QAction* invertIsoLineAct = viewMenu.addAction("Invert iso line visibility"); + QAction* activateIsoLineAct = viewMenu.addAction("Activate all iso lines"); + QAction* deactivateIsoLineAct = viewMenu.addAction("Deactivate all iso lines"); + viewMenu.addSeparator(); + QAction* invertColorWashAct = viewMenu.addAction("Invert color wash visibility"); + QAction* activateColorWashAct = viewMenu.addAction("Activate all color wash levels"); + QAction* deactivateColorWashAct = viewMenu.addAction("Deactivate all color wash levels"); + viewMenu.addSeparator(); + QAction* swapAct = viewMenu.addAction("Swap iso line/color wash visibility"); + + QAction* selectedItem = viewMenu.exec(globalPos); + if (selectedItem == invertIsoLineAct) + { + this->m_LevelSetModel->invertVisibilityIsoLines(); + } + else if (selectedItem == activateIsoLineAct) + { + this->m_LevelSetModel->switchVisibilityIsoLines(true); + } + else if (selectedItem == deactivateIsoLineAct) + { + this->m_LevelSetModel->switchVisibilityIsoLines(false); + } + else if (selectedItem == invertColorWashAct) + { + this->m_LevelSetModel->invertVisibilityColorWash(); + } + else if (selectedItem == activateColorWashAct) + { + this->m_LevelSetModel->switchVisibilityColorWash(true); + } + else if (selectedItem == deactivateColorWashAct) + { + this->m_LevelSetModel->switchVisibilityColorWash(false); + } + else if (selectedItem == swapAct) + { + this->m_LevelSetModel->swapVisibility(); + } + else if (selectedItem == addLevelAct) + { + this->m_LevelSetModel->addLevel(); + } + else if (selectedItem == delLevelAct) + { + this->m_LevelSetModel->deleteLevel(selectedIndex); + } +} + +void DoseVisualizationPreferencePage::OnAddPresetClicked(bool checked) +{ + bool done = false; + QString name = tr("new_preset"); + while (!done) + { + bool ok; + name = QInputDialog::getText(m_MainControl, tr("Define name of new preset."), tr("Preset name:"), QLineEdit::Normal, name, &ok); + + if (!ok) + { + return; //cancled by user; + } + + bool uniqueName = m_Presets.find(name.toStdString()) == m_Presets.end(); + if (!uniqueName) + { + QMessageBox box; + box.setText(tr("New preset name is not unique. Please, choose another one.")); + box.exec(); + } + + bool validName = name.indexOf(tr("/")) ==-1; + if (!validName) + { + QMessageBox box; + box.setText(tr("New preset name is not valid. Please don't use \"/\".")); + box.exec(); + } + + done = uniqueName && validName; + } + + mitk::IsoDoseLevelSet::Pointer newSet = mitk::rt::GeneratIsoLevels_Virtuos(); + m_Presets.insert(std::make_pair(name.toStdString(),newSet)); + + m_presetMapChanged = true; + + UpdatePresetsWidgets(); +} + +void DoseVisualizationPreferencePage::OnDelPresetClicked(bool checked) +{ + QListWidgetItem* selectedItem = m_Controls->listPresets->currentItem(); + + if (selectedItem) + { + if (m_Controls->listPresets->count() > 1) + { + m_Presets.erase(selectedItem->text().toStdString()); + + m_presetMapChanged = true; + this->UpdatePresetsWidgets(); + } + } +} + + +void DoseVisualizationPreferencePage::OnResetPresetClicked(bool checked) +{ + QMessageBox box; + box.setText("Do you want to reset the presets?"); + box.setInformativeText("If you reset the presets. All user defined presets will be removed and the default presets will be loaded."); + box.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + box.setDefaultButton(QMessageBox::No); + int ret = box.exec(); + + if (ret == QMessageBox::Yes) + { + mitk::IsoDoseLevelSet::Pointer newSet = mitk::rt::GeneratIsoLevels_Virtuos(); + m_Presets.clear(); + m_Presets.insert(std::make_pair("Virtuos",newSet)); + + m_presetMapChanged = true; + + UpdatePresetsWidgets(); + } +} + + +void DoseVisualizationPreferencePage::OnAddLevelClicked(bool checked) +{ + this->m_LevelSetModel->addLevel(); +} + +void DoseVisualizationPreferencePage::OnDelLevelClicked(bool checked) +{ + QModelIndex selectedIndex = m_Controls->isoLevelSetView->currentIndex(); + + if (!selectedIndex.isValid()) + { + selectedIndex = m_Controls->isoLevelSetView->indexAt(QPoint(1,1)); + } + + this->m_LevelSetModel->deleteLevel(selectedIndex); +} + +void DoseVisualizationPreferencePage::OnReferenceDoseChanged(double dose) +{ + this->m_referenceDoseChanged = true; +}; diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.h new file mode 100644 index 0000000000..ed45400c1b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePage.h @@ -0,0 +1,123 @@ +/*=================================================================== + +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 __DOSE_VISUALIZATION_PREFERENCE_PAGE_H +#define __DOSE_VISUALIZATION_PREFERENCE_PAGE_H + +#include "berryIQtPreferencePage.h" +#include "berryIPreferences.h" + +#include "ui_DoseVisualizationPreferencePageControls.h" + +#include +#include "mitkDoseVisPreferenceHelper.h" + +/*forward declarations*/ +class QmitkIsoDoseLevelSetModel; +class QmitkDoseColorDelegate; +class QmitkDoseValueDelegate; +class QmitkDoseVisualStyleDelegate; + +class QWidget; + +/** +* \class DoseVisualizationPreferencePage +* \brief Preference page for RT Dose visualization +*/ +class DoseVisualizationPreferencePage : public QObject, public berry::IQtPreferencePage +{ + Q_OBJECT + Q_INTERFACES(berry::IPreferencePage) + +public: + DoseVisualizationPreferencePage(); + ~DoseVisualizationPreferencePage(); + + /** + * \brief Called by framework to initialize this preference page, but currently does nothing. + * \param workbench The workbench. + */ + void Init(berry::IWorkbench::Pointer workbench); + + /** + * \brief Called by framework to create the GUI, and connect signals and slots. + * \param widget The Qt widget that acts as parent to all GUI components, as this class itself is not derived from QWidget. + */ + void CreateQtControl(QWidget* widget); + + /** + * \brief Required by framework to get hold of the GUI. + * \return QWidget* the top most QWidget for the GUI. + */ + QWidget* GetQtControl() const; + + /** + * \see IPreferencePage::PerformOk + */ + virtual bool PerformOk(); + + /** + * \see IPreferencePage::PerformCancel + */ + virtual void PerformCancel(); + + /** + * \see IPreferencePage::Update + */ + virtual void Update(); + + public slots: + + void OnCurrentItemChanged ( QListWidgetItem * currentItem, QListWidgetItem * previousItem); + void OnShowContextMenuIsoSet(const QPoint& pos); + void OnAddPresetClicked(bool checked); + void OnDelPresetClicked(bool checked); + void OnResetPresetClicked(bool checked); + void OnAddLevelClicked(bool checked); + void OnDelLevelClicked(bool checked); + void OnReferenceDoseChanged(double dose); + +protected: + + /** Method updates the presets widgets according to the internal members*/ + void UpdatePresetsWidgets(); + /** Method actualizes the level set model and edit buttons according to the currently selected item in the presets list view*/ + void UpdateLevelSetWidgets(); + + /** Method returns the iso dose level set selected in the preset lists. May return NULL if no preset is selected.*/ + mitk::IsoDoseLevelSet* GetSelectedIsoLevelSet(); + + QWidget *m_MainControl; + Ui::DoseVisualizationPreferencePageControls* m_Controls; + + berry::IPreferences::Pointer m_DoseVisNode; + + typedef mitk::rt::PresetMapType PresetMapType; + PresetMapType m_Presets; + std::string m_selectedPresetName; + + bool m_referenceDoseChanged; + bool m_presetMapChanged; + + QmitkIsoDoseLevelSetModel* m_LevelSetModel; + QmitkDoseColorDelegate* m_DoseColorDelegate; + QmitkDoseValueDelegate* m_DoseValueDelegate; + QmitkDoseVisualStyleDelegate* m_DoseVisualDelegate; + +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePageControls.ui b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePageControls.ui new file mode 100644 index 0000000000..ffbdbcad21 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/DoseVisualizationPreferencePageControls.ui @@ -0,0 +1,307 @@ + + + DoseVisualizationPreferencePageControls + + + + 0 + 0 + 714 + 651 + + + + + 0 + 0 + + + + QmitkTemplate + + + + 5 + + + 5 + + + + + Global viszualization settings: + + + + + + + 0 + 0 + + + + + 105 + 0 + + + + Qt::NoFocus + + + Reference dose [Gy]: + + + + + + + + 0 + 0 + + + + + 65 + 0 + + + + Dose display: + + + + + + + + + relative [%] + + + true + + + + + + + absolute [Gy] + + + + + + + + + Global visibility: + + + + + + + + + Isolines + + + + :/RTUI/eye_open.png + + + + + 24 + 16 + + + + + + + + Colorwash + + + + :/RTUI/eye_open.png + + + + + 24 + 16 + + + + + + + + + + + + + + + + + + 1 + + + 0.100000000000000 + + + 9999.000000000000000 + + + + + + + global sync + + + + + + + + + + + + Iso dose level presets: + + + + 5 + + + 5 + + + + + + 16777215 + 100 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add + + + + + + + Remove + + + + + + + Reset + + + + + + + + + Preset editor: + + + + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + 30 + 20 + + + + 75 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add level + + + + + + + Remove level + + + + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.cpp new file mode 100644 index 0000000000..f24548d4d3 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.cpp @@ -0,0 +1,135 @@ +/*=================================================================== + +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. + +===================================================================*/ + + +// Blueberry +#include +#include + +// Qmitk +#include "LoadingRTView.h" + +// Qt +#include +#include + +#include + +const std::string LoadingRTView::VIEW_ID = "org.mitk.views.loadingrtview"; + +void LoadingRTView::SetFocus(){} + +void LoadingRTView::CreateQtPartControl( QWidget *parent ) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi( parent ); + connect( m_Controls.btnLoadStruct, SIGNAL(clicked()), this, SLOT(LoadRTStructureSet()) ); + connect( m_Controls.btnLoadDose, SIGNAL(clicked()), this, SLOT(LoadRTDoseFile()) ); +} + +void LoadingRTView::LoadRTStructureSet() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.dcm")); + + mitk::DicomSeriesReader::StringContainer files; + QStringList fileNames = dialog.getOpenFileNames(); + if(fileNames.empty()) + { + return; + } + QStringListIterator fileNamesIterator(fileNames); + while(fileNamesIterator.hasNext()) + { + files.push_back(fileNamesIterator.next().toStdString()); + } + + std::string tmp = files.front(); + const char* filename = tmp.c_str(); + char* filenameC = const_cast(filename); + + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.bad()) + { + QMessageBox::information(NULL,"Error","Cant read the file"); + } + DcmDataset *dataset = file.getDataset(); + + mitk::DicomRTReader::Pointer readerRT = mitk::DicomRTReader::New(); + std::deque modelVector; + modelVector = readerRT->ReadDicomFile(filenameC); + + if(modelVector.empty()) + { + QMessageBox::information(NULL, "Error", "Vector is empty ..."); + } + + for(int i=0; iSetData(modelVector.at(i)); + x->SetProperty("name", modelVector.at(i)->GetProperty("name")); + x->SetVisibility(true); + GetDataStorage()->Add(x); + } + mitk::TimeGeometry::Pointer geo = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); + mitk::RenderingManager::GetInstance()->InitializeViews( geo ); +} + +void LoadingRTView::LoadRTDoseFile() +{ + QFileDialog dialog; + dialog.setNameFilter(tr("Images (*.dcm")); + + mitk::DicomSeriesReader::StringContainer files; + QStringList fileNames = dialog.getOpenFileNames(); + if(fileNames.empty()) + { + return; + } + QStringListIterator fileNamesIterator(fileNames); + while(fileNamesIterator.hasNext()) + { + files.push_back(fileNamesIterator.next().toStdString()); + } + + std::string tmp = files.front(); + const char* filename = tmp.c_str(); + char* ncFilename = const_cast(filename); + + mitk::DicomRTReader::Pointer _DicomRTReader = mitk::DicomRTReader::New(); + + DcmFileFormat file; + OFCondition outp = file.loadFile(filename, EXS_Unknown); + if(outp.bad()) + { + QMessageBox::information(NULL,"Error","Cant read the file"); + } + DcmDataset *dataset = file.getDataset(); + + mitk::DataNode::Pointer mitkImage = mitk::DataNode::New(); + mitkImage = _DicomRTReader->LoadRTDose(dataset,ncFilename); + + if(mitkImage.IsNotNull()) + { + GetDataStorage()->Add(mitkImage); + } + +// mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage()); +// mitk::TimeGeometry::Pointer geo3 = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); +// mitk::RenderingManager::GetInstance()->InitializeViews( geo3 ); +} diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.h new file mode 100644 index 0000000000..893221b596 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTView.h @@ -0,0 +1,61 @@ +/*=================================================================== + +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 LoadingRTView_h +#define LoadingRTView_h + +#include + +#include + +#include "ui_LoadingRTViewControls.h" + + +/** + \brief LoadingRTView + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkAbstractView + \ingroup ${plugin_target}_internal +*/ +class LoadingRTView : 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) + Q_OBJECT + + public: + + static const std::string VIEW_ID; + + protected slots: + + void LoadRTDoseFile(); + void LoadRTStructureSet(); + + protected: + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void SetFocus(); + + Ui::LoadingRTViewControls m_Controls; + +}; + +#endif // LoadingRTView_h diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTViewControls.ui b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTViewControls.ui new file mode 100644 index 0000000000..95f9893a6e --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/LoadingRTViewControls.ui @@ -0,0 +1,100 @@ + + + LoadingRTViewControls + + + + 0 + 0 + 288 + 161 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + Loading RT Data + + + + + + + + + + 0 + 60 + + + + RT Struct + + + + :/org.mitk.gui.qt.rt.dosevisualization/resources/icon7.png:/org.mitk.gui.qt.rt.dosevisualization/resources/icon7.png + + + + 50 + 50 + + + + + + + + + 0 + 60 + + + + RT Dose + + + + :/org.mitk.gui.qt.rt.dosevisualization/resources/icon5.png:/org.mitk.gui.qt.rt.dosevisualization/resources/icon5.png + + + + 50 + 50 + + + + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp new file mode 100644 index 0000000000..c4795d588c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.cpp @@ -0,0 +1,845 @@ +/*=================================================================== + +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. + +===================================================================*/ + +// Qt +#include +#include + +// Blueberry +#include +#include + +// MITK +#include + +#include +#include + +// Qmitk +#include "RTDoseVisualizer.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "org_mitk_gui_qt_rt_dosevisualization_Activator.h" + +#include +#include +#include + +#include +#include "QmitkRenderWindow.h" +#include + +#include "mitkSurfaceVtkMapper3D.h" + +#include "mitkSliceNavigationController.h" + +#include "vtkDecimatePro.h" + +const std::string RTDoseVisualizer::VIEW_ID = "org.mitk.views.rt.dosevisualization"; + +RTDoseVisualizer::RTDoseVisualizer() +{ + m_freeIsoValues = mitk::IsoDoseLevelVector::New(); + m_selectedNodeIsoSet = mitk::IsoDoseLevelSet::New(); + + m_freeIsoFilter = vtkSmartPointer::New(); + + m_FreeIsoAdded = false; + m_selectedNode = NULL; + m_selectedPresetName = ""; + m_internalUpdate = false; + m_PrescribedDose_Data = 0.0; +} + +RTDoseVisualizer::~RTDoseVisualizer() +{ + delete m_LevelSetModel; + delete m_DoseColorDelegate; + delete m_DoseValueDelegate; + delete m_DoseVisualDelegate; +} + +void RTDoseVisualizer::InitScrolling(){ + QmitkRenderWindow* rw = this->GetRenderWindowPart()->GetQmitkRenderWindow("axial"); + + itk::MemberCommand::Pointer sliceChangedCommand = + itk::MemberCommand::New(); + sliceChangedCommand->SetCallbackFunction(this, &RTDoseVisualizer::OnSliceChanged); + rw->GetSliceNavigationController()->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(NULL,0), sliceChangedCommand); +} + +void RTDoseVisualizer::SetFocus(){} + +void RTDoseVisualizer::OnSliceChanged(itk::Object *sender, const itk::EventObject &e) +{ + for(int i=0; iRemove(m_StdIsoLines.at(i)); + } + m_StdIsoLines.clear(); + this->UpdateStdIsolines(); + + if(m_FreeIsoAdded) + { + float pref; + //get the iso dose node + mitk::DataNode::Pointer isoNode = this->GetIsoDoseNode(); + isoNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); + mitk::Image::Pointer image = dynamic_cast(isoNode->GetData()); + mitk::Image::Pointer slicedImage = this->GetExtractedSlice(image); + + m_Filters.at(0)->SetInputData(slicedImage->GetVtkImageData()); + m_Filters.at(0)->GenerateValues(1,m_FreeIsoValue->GetDoseValue()*pref,m_FreeIsoValue->GetDoseValue()*pref); + m_Filters.at(0)->Update(); + + m_FreeIsoline->GetData()->GetGeometry()->SetOrigin(slicedImage->GetGeometry()->GetOrigin()); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } +} + +mitk::DataNode::Pointer RTDoseVisualizer::GetIsoDoseNode() +{ + //holt zuerst alle isonodes prüft dann auf visibility und nimmt zuletzt den mit dem höchsten layer + mitk::NodePredicateProperty::Pointer isDosePredicate = mitk::NodePredicateProperty::New(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),mitk::BoolProperty::New(true)); + mitk::DataStorage::SetOfObjects::ConstPointer allIsoDoseNodes = this->GetDataStorage()->GetSubset(isDosePredicate); + int tmp = -1; + int layer = -1; + mitk::DataNode::Pointer isoNode = mitk::DataNode::New(); + for(mitk::DataStorage::SetOfObjects::ConstIterator itIsoDose = allIsoDoseNodes->Begin(); itIsoDose != allIsoDoseNodes->End(); ++itIsoDose) + { + bool isVisible(false); + itIsoDose.Value()->GetBoolProperty("visible",isVisible); + if(isVisible) + { + if(itIsoDose.Value()->GetIntProperty("layer",tmp) && tmp > layer) + { + isoNode = itIsoDose.Value(); + } + } + } + if(isoNode.IsNotNull()) + return isoNode; + else + return NULL; +} + +void RTDoseVisualizer::CreateQtPartControl( QWidget *parent ) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi( parent ); + + m_LevelSetModel = new QmitkIsoDoseLevelSetModel(this); + m_LevelSetModel->setVisibilityEditOnly(true); + m_DoseColorDelegate = new QmitkDoseColorDelegate(this); + m_DoseValueDelegate = new QmitkDoseValueDelegate(this); + m_DoseVisualDelegate = new QmitkDoseVisualStyleDelegate(this); + + this->UpdateByPreferences(); + this->ActualizeIsoLevelsForAllDoseDataNodes(); + this->ActualizeReferenceDoseForAllDoseDataNodes(); + this->ActualizeDisplayStyleForAllDoseDataNodes(); + + this->m_Controls.isoLevelSetView->setModel(m_LevelSetModel); + this->m_Controls.isoLevelSetView->setItemDelegateForColumn(0,m_DoseColorDelegate); + this->m_Controls.isoLevelSetView->setItemDelegateForColumn(1,m_DoseValueDelegate); + this->m_Controls.isoLevelSetView->setItemDelegateForColumn(2,m_DoseVisualDelegate); + this->m_Controls.isoLevelSetView->setItemDelegateForColumn(3,m_DoseVisualDelegate); + this->m_Controls.isoLevelSetView->setContextMenuPolicy(Qt::CustomContextMenu); + + this->m_Controls.btnRemoveFreeValue->setDisabled(true); + + connect(m_Controls.btnConvert, SIGNAL(clicked()), this, SLOT(OnConvertButtonClicked())); + connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), this, SLOT(OnReferenceDoseChanged(double))); + connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), m_LevelSetModel, SLOT(setReferenceDose(double))); + connect(m_Controls.radioAbsDose, SIGNAL(toggled(bool)), m_LevelSetModel, SLOT(setShowAbsoluteDose(bool))); + connect(m_Controls.radioAbsDose, SIGNAL(toggled(bool)), this, SLOT(OnAbsDoseToggled(bool))); + connect(m_Controls.btnAddFreeValue, SIGNAL(clicked()), this, SLOT(OnAddFreeValueClicked())); + connect(m_Controls.btnRemoveFreeValue, SIGNAL(clicked()), this, SLOT(OnRemoveFreeValueClicked())); + connect(m_Controls.checkGlobalVisColorWash, SIGNAL(toggled(bool)), this, SLOT(OnGlobalVisColorWashToggled(bool))); + connect(m_Controls.checkGlobalVisIsoLine, SIGNAL(toggled(bool)), this, SLOT(OnGlobalVisIsoLineToggled(bool))); + connect(m_Controls.isoLevelSetView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnShowContextMenuIsoSet(const QPoint&))); + connect(m_Controls.comboPresets, SIGNAL(currentIndexChanged ( const QString&)), this, SLOT(OnCurrentPresetChanged(const QString&))); + connect(m_Controls.btnUsePrescribedDose, SIGNAL(clicked()), this, SLOT(OnUsePrescribedDoseClicked())); + + ctkServiceReference ref = mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()->getServiceReference(); + + ctkDictionary propsForSlot; + if (ref) + { + ctkEventAdmin* eventAdmin = mitk::org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext()->getService(ref); + + propsForSlot[ctkEventConstants::EVENT_TOPIC] = mitk::rt::CTKEventConstants::TOPIC_ISO_DOSE_LEVEL_PRESETS_CHANGED.c_str(); + eventAdmin->subscribeSlot(this, SLOT(OnHandleCTKEventPresetsChanged(ctkEvent)), propsForSlot); + + propsForSlot[ctkEventConstants::EVENT_TOPIC] = mitk::rt::CTKEventConstants::TOPIC_REFERENCE_DOSE_CHANGED.c_str(); + eventAdmin->subscribeSlot(this, SLOT(OnHandleCTKEventReferenceDoseChanged(ctkEvent)), propsForSlot); + } + + this->UpdateBySelectedNode(); +} + +void RTDoseVisualizer::OnReferenceDoseChanged(double value) +{ + if (! m_internalUpdate) + { + mitk::DoseValueAbs referenceDose = 0.0; + bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); + + if (globalSync) + { + mitk::rt::SetReferenceDoseValue(globalSync, value); + this->ActualizeReferenceDoseForAllDoseDataNodes(); + } + else + { + if (this->m_selectedNode.IsNotNull()) + { + this->m_selectedNode->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), value); + } + } + if (this->m_selectedNode.IsNotNull()) + { + mitk::TransferFunction::ControlPoints scalarOpacityPoints; + scalarOpacityPoints.push_back( std::make_pair(0, 1 ) ); + vtkSmartPointer transferFunction = vtkSmartPointer::New(); + mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; + for(mitk::IsoDoseLevelSet::ConstIterator setIT = isoDoseLevelSet->Begin(); setIT != isoDoseLevelSet->End(); ++setIT) + { + float *hsv = new float[3]; + vtkSmartPointer cCalc = vtkSmartPointer::New(); + if(setIT->GetVisibleColorWash()){ + cCalc->RGBToHSV(setIT->GetColor()[0],setIT->GetColor()[1],setIT->GetColor()[2],&hsv[0],&hsv[1],&hsv[2]); + transferFunction->AddHSVPoint(setIT->GetDoseValue()*value,hsv[0],hsv[1],hsv[2],1.0,1.0); + } + else + { + scalarOpacityPoints.push_back( std::make_pair(setIT->GetDoseValue()*value, 1 ) ); + } + } + mitk::TransferFunction::Pointer mitkTransFunc = mitk::TransferFunction::New(); + mitk::TransferFunctionProperty::Pointer mitkTransFuncProp = mitk::TransferFunctionProperty::New(); + mitkTransFunc->SetColorTransferFunction(transferFunction); + mitkTransFunc->SetScalarOpacityPoints(scalarOpacityPoints); + mitkTransFuncProp->SetValue(mitkTransFunc); + + mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); + renderingMode->SetValue(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR); + + m_selectedNode->SetProperty("Image Rendering.Transfer Function", mitkTransFuncProp); + m_selectedNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + } +} + +void RTDoseVisualizer::OnAddFreeValueClicked() +{ + QColor newColor; + //Use HSV schema of QColor to calculate a different color depending on the + //number of already existing free iso lines. + newColor.setHsv((m_freeIsoValues->Size()*85)%360,255,255); + mitk::Color mColor; + mColor[0]=newColor.redF(); + mColor[1]=newColor.greenF(); + mColor[2]=newColor.blueF(); + + mitk::DataNode::Pointer isoNode = this->UpdatePolyData(1,m_Controls.spinReferenceDose->value()*0.5,m_Controls.spinReferenceDose->value()*0.5); + isoNode->SetColor(mColor); + m_FreeIsoLines.push_back(isoNode); + + mitk::IsoDoseLevel::ColorType color; + color[0] = newColor.redF(); + color[1] = newColor.greenF(); + color[2] = newColor.blueF(); + m_freeIsoValues->push_back(mitk::IsoDoseLevel::New(0.5,color,true,false)); + m_FreeIsoValue = mitk::IsoDoseLevel::New(0.5,color,true,false); + UpdateFreeIsoValues(); + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + if(m_FreeIsoLines.size()>=1) + { + this->m_Controls.btnAddFreeValue->setDisabled(true); + m_FreeIsoAdded = true; + } + this->m_Controls.btnRemoveFreeValue->setEnabled(true); +} + +void RTDoseVisualizer::OnRemoveFreeValueClicked() +{ + m_freeIsoValues->pop_back(); + mitk::DataNode::Pointer isoNode = m_FreeIsoLines.at(m_FreeIsoLines.size()-1); + m_FreeIsoLines.pop_back(); + m_Filters.pop_back(); + if(m_FreeIsoLines.empty()) + this->m_Controls.btnRemoveFreeValue->setDisabled(true); + if(m_FreeIsoLines.size()<1) + { + m_FreeIsoAdded = false; + this->m_Controls.btnAddFreeValue->setEnabled(true); + } + this->GetDataStorage()->Remove(isoNode); + UpdateFreeIsoValues(); +} + +void RTDoseVisualizer::OnUsePrescribedDoseClicked() +{ + m_Controls.spinReferenceDose->setValue(this->m_PrescribedDose_Data); +} + + +void RTDoseVisualizer::OnShowContextMenuIsoSet(const QPoint& pos) +{ + QPoint globalPos = m_Controls.isoLevelSetView->viewport()->mapToGlobal(pos); + + QMenu viewMenu; + QAction* invertIsoLineAct = viewMenu.addAction("Invert iso line visibility"); + QAction* activateIsoLineAct = viewMenu.addAction("Activate all iso lines"); + QAction* deactivateIsoLineAct = viewMenu.addAction("Deactivate all iso lines"); + viewMenu.addSeparator(); + QAction* invertColorWashAct = viewMenu.addAction("Invert color wash visibility"); + QAction* activateColorWashAct = viewMenu.addAction("Activate all color wash levels"); + QAction* deactivateColorWashAct = viewMenu.addAction("Deactivate all color wash levels"); + viewMenu.addSeparator(); + QAction* swapAct = viewMenu.addAction("Swap iso line/color wash visibility"); + // ... + + QAction* selectedItem = viewMenu.exec(globalPos); + if (selectedItem == invertIsoLineAct) + { + this->m_LevelSetModel->invertVisibilityIsoLines(); + } + else if (selectedItem == activateIsoLineAct) + { + this->m_LevelSetModel->switchVisibilityIsoLines(true); + } + else if (selectedItem == deactivateIsoLineAct) + { + this->m_LevelSetModel->switchVisibilityIsoLines(false); + } + else if (selectedItem == invertColorWashAct) + { + this->m_LevelSetModel->invertVisibilityColorWash(); + } + else if (selectedItem == activateColorWashAct) + { + this->m_LevelSetModel->switchVisibilityColorWash(true); + } + else if (selectedItem == deactivateColorWashAct) + { + this->m_LevelSetModel->switchVisibilityColorWash(false); + } + else if (selectedItem == swapAct) + { + this->m_LevelSetModel->swapVisibility(); + } +} + +void RTDoseVisualizer::UpdateFreeIsoValues() +{ + this->m_Controls.listFreeValues->clear(); + + for (mitk::IsoDoseLevelVector::Iterator pos = this->m_freeIsoValues->Begin(); pos != this->m_freeIsoValues->End(); ++pos) + { + QListWidgetItem* item = new QListWidgetItem; + item->setSizeHint(QSize(0,25)); + QmitkFreeIsoDoseLevelWidget* widget = new QmitkFreeIsoDoseLevelWidget; + + float pref; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); + + widget->setIsoDoseLevel(pos->Value().GetPointer()); + widget->setReferenceDose(pref); + connect(m_Controls.spinReferenceDose, SIGNAL(valueChanged(double)), widget, SLOT(setReferenceDose(double))); + connect(widget,SIGNAL(ColorChanged(mitk::IsoDoseLevel*)), this, SLOT(UpdateFreeIsoLineColor(mitk::IsoDoseLevel*))); + connect(widget,SIGNAL(ValueChanged(mitk::IsoDoseLevel*,mitk::DoseValueRel)), this, SLOT(UpdateFreeIsoLine(mitk::IsoDoseLevel*,mitk::DoseValueRel))); + + this->m_Controls.listFreeValues->addItem(item); + this->m_Controls.listFreeValues->setItemWidget(item,widget); + } +} + +void RTDoseVisualizer::UpdateFreeIsoLineColor(mitk::IsoDoseLevel *level) +{ + //push it in and get the key! +// m_freeIsoValues + ::itk::RGBPixel color = level->GetColor(); + mitk::Color mColor; + mColor[0]=color.GetRed(); + mColor[1]=color.GetGreen(); + mColor[2]=color.GetBlue(); + m_FreeIsoline->SetColor(mColor); +} + +void RTDoseVisualizer::UpdateFreeIsoLine(mitk::IsoDoseLevel * level, mitk::DoseValueRel old) +{ + float pref; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); + mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); + mitk::Image::Pointer slicedImage = this->GetExtractedSlice(image); + + m_FreeIsoValue = level; +// m_freeIsoValues->at(0) = level; + + m_Filters.at(0)->SetInputData(slicedImage->GetVtkImageData()); + m_Filters.at(0)->GenerateValues(1,level->GetDoseValue()*pref,level->GetDoseValue()*pref); + m_Filters.at(0)->Update(); + + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void RTDoseVisualizer::OnAbsDoseToggled(bool showAbs) +{ + if (! m_internalUpdate) + { + mitk::rt::SetDoseDisplayAbsolute(showAbs); + this->ActualizeDisplayStyleForAllDoseDataNodes(); + } +} + +void RTDoseVisualizer::OnGlobalVisColorWashToggled(bool showColorWash) +{ + if (m_selectedNode.IsNotNull()) + { + m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(), showColorWash); + } +} + +void RTDoseVisualizer::OnGlobalVisIsoLineToggled(bool showIsoLines) +{ + if (m_selectedNode.IsNotNull()) + { + m_selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME.c_str(), showIsoLines); + mitk::NodePredicateProperty::Pointer isoProp = mitk::NodePredicateProperty:: + New(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); + mitk::DataStorage::SetOfObjects::ConstPointer isoSet = this->GetDataStorage()->GetSubset(isoProp); + for(mitk::DataStorage::SetOfObjects::ConstIterator iso = isoSet->Begin(); iso!=isoSet->End(); ++iso) + { + mitk::DataNode::Pointer node = iso.Value(); + node->SetVisibility(showIsoLines); + } + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); + } +} + + +void RTDoseVisualizer::OnConvertButtonClicked() +{ + this->InitScrolling(); + + QList dataNodes = this->GetDataManagerSelection(); + + mitk::DataNode* selectedNode = NULL; + + if (!dataNodes.empty()) + { + selectedNode = dataNodes[0]; + } + + bool isDoseNode = false; + if(selectedNode && selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),isDoseNode) && isDoseNode) + { + selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), true); + selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(), true); + selectedNode->SetBoolProperty(mitk::rt::Constants::DOSE_SHOW_ISOLINES_PROPERTY_NAME.c_str(), true); + selectedNode->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), m_Controls.spinReferenceDose->value()); + + mitk::IsoDoseLevelSet::Pointer clonedPreset = this->m_Presets[this->m_selectedPresetName]->Clone(); + mitk::IsoDoseLevelSetProperty::Pointer levelSetProp = mitk::IsoDoseLevelSetProperty::New(clonedPreset); + selectedNode->SetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),levelSetProp); + + float prescribed; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),prescribed); + + vtkSmartPointer transferFunction = vtkSmartPointer::New(); + + mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; + + float pref; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); + + //Generating the Colorwash + for(mitk::IsoDoseLevelSet::ConstIterator setIT = isoDoseLevelSet->Begin(); setIT != isoDoseLevelSet->End(); ++setIT) + { + float *hsv = new float[3]; + //used for transfer rgb to hsv + vtkSmartPointer cCalc = vtkSmartPointer::New(); + if(setIT->GetVisibleColorWash()){ + cCalc->RGBToHSV(setIT->GetColor()[0],setIT->GetColor()[1],setIT->GetColor()[2],&hsv[0],&hsv[1],&hsv[2]); + transferFunction->AddHSVPoint(setIT->GetDoseValue()*pref,hsv[0],hsv[1],hsv[2],1.0,1.0); + } + } + + //Generating the standard isolines + this->UpdateStdIsolines(); + + mitk::TransferFunction::Pointer mitkTransFunc = mitk::TransferFunction::New(); + mitk::TransferFunctionProperty::Pointer mitkTransFuncProp = mitk::TransferFunctionProperty::New(); + mitkTransFunc->SetColorTransferFunction(transferFunction); + mitkTransFuncProp->SetValue(mitkTransFunc); + + mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); + renderingMode->SetValue(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR); + + selectedNode->SetProperty("Image Rendering.Transfer Function", mitkTransFuncProp); + selectedNode->SetProperty("Image Rendering.Mode", renderingMode); + m_selectedNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); + + mitk::IsoDoseLevelVector::Pointer levelVector = mitk::IsoDoseLevelVector::New(); + mitk::IsoDoseLevelVectorProperty::Pointer levelVecProp = mitk::IsoDoseLevelVectorProperty::New(levelVector); + selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),levelVecProp); + + UpdateBySelectedNode(); + + mitk::TimeGeometry::Pointer geo = this->GetDataStorage()->ComputeBoundingGeometry3D(this->GetDataStorage()->GetAll()); + mitk::RenderingManager::GetInstance()->InitializeViews( geo ); + } +} + +const mitk::Geometry2D* RTDoseVisualizer::GetGeometry2D(char* dim) +{ + QmitkRenderWindow* rw = this->GetRenderWindowPart()->GetQmitkRenderWindow(dim); + const mitk::Geometry2D* worldGeo = rw->GetRenderer()->GetCurrentWorldGeometry2D(); + return worldGeo; +} + +mitk::Image::Pointer RTDoseVisualizer::GetExtractedSlice(mitk::Image::Pointer image) +{ + mitk::ExtractSliceFilter::Pointer extractFilter = mitk::ExtractSliceFilter::New(); + extractFilter->SetInput(image); + extractFilter->SetWorldGeometry(this->GetGeometry2D("axial")); + extractFilter->SetResliceTransformByGeometry( image->GetTimeGeometry()->GetGeometryForTimeStep(0) ); + extractFilter->Update(); + mitk::Image::Pointer reslicedImage = extractFilter->GetOutput(); + return reslicedImage; +} + +mitk::DataNode::Pointer RTDoseVisualizer::UpdatePolyData(int num, double min, double max) +{ + mitk::Image::Pointer image = dynamic_cast(m_selectedNode->GetData()); + mitk::Image::Pointer reslicedImage = this->GetExtractedSlice(image); + + vtkSmartPointer contourFilter = vtkSmartPointer::New(); + m_Filters.push_back(contourFilter); + contourFilter->SetInputData(reslicedImage->GetVtkImageData()); + contourFilter->GenerateValues(num,min,max); + contourFilter->Update(); + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData =contourFilter->GetOutput(); + + mitk::Surface::Pointer isoline = mitk::Surface::New(); + isoline->SetVtkPolyData(polyData); + isoline->SetGeometry(reslicedImage->GetGeometry()->Clone()); + mitk::Vector3D spacing; + spacing.Fill(1); + isoline->GetGeometry()->SetSpacing(spacing); + + mitk::DataNode::Pointer isolineNode = mitk::DataNode::New(); + isolineNode->SetData(isoline); + mitk::SurfaceVtkMapper3D::Pointer mapper = mitk::SurfaceVtkMapper3D::New(); + isolineNode->SetMapper(1, mapper); + isolineNode->SetName("Isoline1"); + isolineNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); + isolineNode->SetProperty( "line width", mitk::IntProperty::New(1)); + isolineNode->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false)); + isolineNode->SetBoolProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),true); + m_FreeIsoline = isolineNode; + this->GetDataStorage()->Add(isolineNode); + return isolineNode; +} + +void RTDoseVisualizer::UpdateStdIsolines() +{ + bool isDoseNode = false; + mitk::IsoDoseLevelSet::Pointer isoDoseLevelSet = this->m_Presets[this->m_selectedPresetName]; + mitk::DataNode::Pointer isoDataNode = this->GetIsoDoseNode(); + if(isoDataNode && isoDataNode->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),isDoseNode) && isDoseNode) + { + mitk::Image::Pointer image = dynamic_cast(isoDataNode->GetData()); + mitk::Image::Pointer reslicedImage = this->GetExtractedSlice(image); + + reslicedImage->SetSpacing(image->GetGeometry()->GetSpacing()); + + float pref; + isoDataNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),pref); + + unsigned int count (0); + for(mitk::IsoDoseLevelSet::ConstIterator doseIT = isoDoseLevelSet->Begin(); doseIT!=isoDoseLevelSet->End();++doseIT) + { + if(doseIT->GetVisibleIsoLine()){ + ++count; + vtkSmartPointer isolineFilter = vtkSmartPointer::New(); + isolineFilter->SetInputData(reslicedImage->GetVtkImageData()); + isolineFilter->GenerateValues(1,doseIT->GetDoseValue()*pref,doseIT->GetDoseValue()*pref); + isolineFilter->Update(); + vtkSmartPointer polyData = vtkSmartPointer::New(); + polyData=isolineFilter->GetOutput(); + + mitk::Surface::Pointer surface = mitk::Surface::New(); + + surface->SetVtkPolyData(polyData); + surface->SetGeometry(reslicedImage->GetGeometry()->Clone()); + mitk::Vector3D spacing; + spacing.Fill(1); + surface->GetGeometry()->SetSpacing(spacing); + + mitk::DataNode::Pointer isoNode = mitk::DataNode::New(); + isoNode->SetData(surface); + mitk::SurfaceVtkMapper3D::Pointer mapper = mitk::SurfaceVtkMapper3D::New(); + mitk::Color color; + color[0]=doseIT->GetColor()[0];color[1]=doseIT->GetColor()[1];color[2]=doseIT->GetColor()[2]; + isoNode->SetMapper(1,mapper); + isoNode->SetColor(color); + isoNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); + isoNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false) ); + isoNode->SetProperty( "line width", mitk::IntProperty::New(1)); + std::stringstream strstr; + strstr<<"StdIsoline_"; + strstr<SetName(strstr.str()); + isoNode->SetBoolProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),true); + m_StdIsoLines.push_back(isoNode); + this->GetDataStorage()->Add(isoNode, isoDataNode); + } + } + } +} + +void RTDoseVisualizer::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes ) +{ + QList dataNodes = this->GetDataManagerSelection(); + + mitk::DataNode* selectedNode = NULL; + + if (!dataNodes.empty()) + { + bool isDoseNode = false; + dataNodes[0]->GetBoolProperty(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(),isDoseNode); + + if (isDoseNode) + { + selectedNode = dataNodes[0]; + } + } + + if (selectedNode != m_selectedNode.GetPointer()) + { + m_selectedNode = selectedNode; + } + + UpdateBySelectedNode(); +} + +void RTDoseVisualizer::UpdateBySelectedNode() +{ + m_Controls.groupNodeSpecific->setEnabled(m_selectedNode.IsNotNull()); + m_Controls.groupFreeValues->setEnabled(m_selectedNode.IsNotNull()); + + if(m_selectedNode.IsNull()) + { + m_Controls.NrOfFractions->setText(QString("N/A. No dose selected")); + m_Controls.prescribedDoseSpecific->setText(QString("N/A. No dose selected")); + m_freeIsoValues = mitk::IsoDoseLevelVector::New(); + UpdateFreeIsoValues(); + } + else + { + //dose specific information + int fracCount = 1; + m_selectedNode->GetIntProperty(mitk::rt::Constants::DOSE_FRACTION_COUNT_PROPERTY_NAME.c_str(),fracCount); + m_Controls.NrOfFractions->setText(QString::number(fracCount)); + + m_PrescribedDose_Data = 0.0; + + float tmp; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::PRESCRIBED_DOSE_PROPERTY_NAME.c_str(),tmp); + m_PrescribedDose_Data = (double)tmp; + + m_Controls.prescribedDoseSpecific->setText(QString::number(m_PrescribedDose_Data)); + + //free iso lines + mitk::IsoDoseLevelVectorProperty::Pointer propIsoVector; + m_selectedNode->GetProperty(propIsoVector, mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str()); + + if (propIsoVector.IsNull()) + { + m_freeIsoValues = mitk::IsoDoseLevelVector::New(); + propIsoVector = mitk::IsoDoseLevelVectorProperty::New(m_freeIsoValues); + m_selectedNode->SetProperty(mitk::rt::Constants::DOSE_FREE_ISO_VALUES_PROPERTY_NAME.c_str(),propIsoVector); + } + else + { + m_freeIsoValues = propIsoVector->GetValue(); + } + + UpdateFreeIsoValues(); + + //global dose issues + bool showIsoLine = false; + m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(),showIsoLine); + m_Controls.checkGlobalVisIsoLine->setChecked(showIsoLine); + + bool showColorWash = false; + m_selectedNode->GetBoolProperty(mitk::rt::Constants::DOSE_SHOW_COLORWASH_PROPERTY_NAME.c_str(),showColorWash); + m_Controls.checkGlobalVisColorWash->setChecked(showColorWash); + + float referenceDose = 0.0; + m_selectedNode->GetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(),referenceDose); + m_Controls.spinReferenceDose->setValue(referenceDose); + + mitk::IsoDoseLevelSetProperty::Pointer propIsoSet = + dynamic_cast(m_selectedNode->GetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str())); + + if (propIsoSet) + { + this->m_selectedNodeIsoSet = propIsoSet->GetValue(); + this->m_LevelSetModel->setIsoDoseLevelSet(m_selectedNodeIsoSet); + } + } +} + +void RTDoseVisualizer::UpdateByPreferences() +{ + m_Presets = mitk::rt::LoadPresetsMap(); + m_internalUpdate = true; + m_Controls.comboPresets->clear(); + this->m_selectedPresetName = mitk::rt::GetSelectedPresetName(); + + int index = 0; + int selectedIndex = -1; + for (mitk::rt::PresetMapType::const_iterator pos = m_Presets.begin(); pos != m_Presets.end(); ++pos, ++index) + { + m_Controls.comboPresets->addItem(QString(pos->first.c_str())); + if (this->m_selectedPresetName == pos->first) + { + selectedIndex = index; + } + } + + if (selectedIndex == -1) + { + selectedIndex = 0; + MITK_WARN << "Error. Cannot iso dose level preset specified in preferences does not exist. Preset name: "<m_selectedPresetName; + this->m_selectedPresetName = m_Presets.begin()->first; + mitk::rt::SetSelectedPresetName(this->m_selectedPresetName); + MITK_INFO << "Changed selected iso dose level preset to first existing preset. New preset name: "<m_selectedPresetName; + } + + m_Controls.comboPresets->setCurrentIndex(selectedIndex); + + this->m_selectedNodeIsoSet = this->m_Presets[this->m_selectedPresetName]; + this->m_LevelSetModel->setIsoDoseLevelSet(m_selectedNodeIsoSet); + + mitk::DoseValueAbs referenceDose = 0.0; + bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); + if (globalSync || this->m_selectedNode.IsNull()) + { + m_Controls.spinReferenceDose->setValue(referenceDose); + } + + bool displayAbsoluteDose = mitk::rt::GetDoseDisplayAbsolute(); + m_Controls.radioAbsDose->setChecked(displayAbsoluteDose); + m_Controls.radioRelDose->setChecked(!displayAbsoluteDose); + this->m_LevelSetModel->setShowAbsoluteDose(displayAbsoluteDose); + m_internalUpdate = false; +} + +void RTDoseVisualizer::OnCurrentPresetChanged(const QString& presetName) +{ + if (! m_internalUpdate) + { + mitk::rt::SetSelectedPresetName(presetName.toStdString()); + this->UpdateByPreferences(); + this->ActualizeIsoLevelsForAllDoseDataNodes(); + this->UpdateBySelectedNode(); + } +} + +void RTDoseVisualizer::ActualizeIsoLevelsForAllDoseDataNodes() +{ + std::string presetName = mitk::rt::GetSelectedPresetName(); + + mitk::rt::PresetMapType presetMap = mitk::rt::LoadPresetsMap(); + + mitk::NodePredicateProperty::Pointer isDoseNode = mitk::NodePredicateProperty::New(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetSubset(isDoseNode); + + mitk::IsoDoseLevelSet* selectedPreset = presetMap[presetName]; + + if (!selectedPreset) + { + mitkThrow() << "Error. Cannot actualize iso dose level preset. Selected preset idoes not exist. Preset name: "<begin(); pos != nodes->end(); ++pos) + { + mitk::IsoDoseLevelSet::Pointer clonedPreset = selectedPreset->Clone(); + mitk::IsoDoseLevelSetProperty::Pointer propIsoSet = mitk::IsoDoseLevelSetProperty::New(clonedPreset); + (*pos)->SetProperty(mitk::rt::Constants::DOSE_ISO_LEVELS_PROPERTY_NAME.c_str(),propIsoSet); + } +} + +void RTDoseVisualizer::ActualizeReferenceDoseForAllDoseDataNodes() +{ + /** @TODO Klären ob diese präsentations info genauso wie*/ + mitk::DoseValueAbs value = 0; + bool sync = mitk::rt::GetReferenceDoseValue(value); + + if (sync) + { + mitk::NodePredicateProperty::Pointer isDoseNode = mitk::NodePredicateProperty::New(mitk::rt::Constants::DOSE_PROPERTY_NAME.c_str(), mitk::BoolProperty::New(true)); + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetSubset(isDoseNode); + + for(mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); ++pos) + { + (*pos)->SetFloatProperty(mitk::rt::Constants::REFERENCE_DOSE_PROPERTY_NAME.c_str(), value); + } + } +} + +void RTDoseVisualizer::ActualizeDisplayStyleForAllDoseDataNodes() +{ + /** @TODO Klären ob diese präsentations info global oder auch per node gespeichert wird*/ +} + +void RTDoseVisualizer::OnHandleCTKEventReferenceDoseChanged(const ctkEvent& event) +{ + mitk::DoseValueAbs referenceDose = 0.0; + bool globalSync = mitk::rt::GetReferenceDoseValue(referenceDose); + + this->m_Controls.spinReferenceDose->setValue(referenceDose); +} + +void RTDoseVisualizer::OnHandleCTKEventPresetsChanged(const ctkEvent& event) +{ + std::string currentPresetName = mitk::rt::GetSelectedPresetName(); + + this->OnCurrentPresetChanged(QString::fromStdString(currentPresetName)); +} diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h new file mode 100644 index 0000000000..854feebfd1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizer.h @@ -0,0 +1,207 @@ +/*=================================================================== + +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 RTDoseVisualizer_h +#define RTDoseVisualizer_h + +#include + +#include +#include + +#include + +#include "ui_RTDoseVisualizerControls.h" + +#include + +#include + +#include "mitkDoseVisPreferenceHelper.h" + +// Shader +#include +#include +#include + +#include +#include + +#include + +#include +#include + +/*forward declarations*/ +class QmitkIsoDoseLevelSetModel; +class QmitkDoseColorDelegate; +class QmitkDoseValueDelegate; +class QmitkDoseVisualStyleDelegate; +class ctkEvent; + +/** +\brief RTDoseVisualizer + +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + +\sa QmitkAbstractView +\ingroup ${plugin_target}_internal +*/ +class RTDoseVisualizer : 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) + Q_OBJECT + +public: + + RTDoseVisualizer(); + virtual ~RTDoseVisualizer(); + static const std::string VIEW_ID; + + void OnSliceChanged(itk::Object *sender, const itk::EventObject &e); + + protected slots: + + void OnConvertButtonClicked(); + + void OnAddFreeValueClicked(); + + void OnRemoveFreeValueClicked(); + + void OnUsePrescribedDoseClicked(); + + void OnAbsDoseToggled(bool); + + void OnGlobalVisColorWashToggled(bool); + + void OnGlobalVisIsoLineToggled(bool); + + void OnShowContextMenuIsoSet(const QPoint&); + + void OnCurrentPresetChanged(const QString&); + + void OnReferenceDoseChanged(double); + + void OnHandleCTKEventReferenceDoseChanged(const ctkEvent& event); + + void OnHandleCTKEventPresetsChanged(const ctkEvent& event); + + void UpdateFreeIsoLine(mitk::IsoDoseLevel*level, mitk::DoseValueRel old); + + void UpdateFreeIsoLineColor(mitk::IsoDoseLevel* level); + +protected: + + void InitScrolling(); + + virtual void CreateQtPartControl(QWidget *parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged( berry::IWorkbenchPart::Pointer source, + const QList& nodes ); + + /** Method updates the list widget according to the current m_freeIsoValues.*/ + void UpdateFreeIsoValues(); + + /** Update the members according to the currently selected node */ + void UpdateBySelectedNode(); + + /** Update the member widgets according to the information stored in the application preferences*/ + void UpdateByPreferences(); + + /**helper function that iterates throug all data nodes and sets there iso level set property + according to the selected preset. + @TODO: should be moved outside the class, to be available for other classes at well.*/ + void ActualizeIsoLevelsForAllDoseDataNodes(); + + /**helper function that iterates throug all data nodes and sets there reference dose value + according to the preference. + @TODO: should be moved outside the class, to be available for other classes at well.*/ + void ActualizeReferenceDoseForAllDoseDataNodes(); + + /**helper function that iterates through all data nodes and sets there dose display style (relative/absolute) + according to the preference. + @TODO: should be moved outside the class, to be available for other classes at well.*/ + void ActualizeDisplayStyleForAllDoseDataNodes(); + + /** + * @brief UpdatePolyData + * @param num + * @param min + * @param max + * @return + */ + mitk::DataNode::Pointer UpdatePolyData(int num, double min, double max); + + mitk::DataNode::Pointer GetIsoDoseNode(); + + /** + * @brief Calculates the isolines for the dose image + * Number, value and color depends on the selected preset + */ + void UpdateStdIsolines(); + + /** + * @brief Get the active axial slice as 2D image + * Uses a mitkExtractSliceFilter for getting the 2D slice of the + * axial view + * @param image the mitkImage which is shown in the axial window + * @return the 2D mitkImage slice + */ + mitk::Image::Pointer GetExtractedSlice(mitk::Image::Pointer image); + + /** + * @brief Get the mitkGeometry2D of a specific render window + * @param dim the name of the render window + * @return the mitkGeometry2D of the render window + */ + const mitk::Geometry2D* GetGeometry2D(char* dim); + + Ui::RTDoseVisualizerControls m_Controls; + mitk::DataNode::Pointer m_selectedNode; + mitk::IsoDoseLevel::Pointer m_FreeIsoValue; + mitk::IsoDoseLevelVector::Pointer m_freeIsoValues; + std::vector m_FreeIsoLines; + std::vector m_StdIsoLines; + /** Iso level set of the current node. Should normaly be a clone of the + * current iso preset. It held as own member because visibility + * settings may differ.*/ + mitk::IsoDoseLevelSet::Pointer m_selectedNodeIsoSet; + mitk::rt::PresetMapType m_Presets; + std::string m_selectedPresetName; + + mitk::DataNode::Pointer m_FreeIsoline; + bool m_FreeIsoAdded; + + /** Prescribed Dose of the selected data.*/ + mitk::DoseValueAbs m_PrescribedDose_Data; + + QmitkIsoDoseLevelSetModel* m_LevelSetModel; + QmitkDoseColorDelegate* m_DoseColorDelegate; + QmitkDoseValueDelegate* m_DoseValueDelegate; + QmitkDoseVisualStyleDelegate* m_DoseVisualDelegate; + + vtkSmartPointer m_freeIsoFilter; + std::vector< vtkSmartPointer > m_Filters; + + bool m_internalUpdate; +}; + +#endif // RTDoseVisualizer_h diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui new file mode 100644 index 0000000000..ad64bd4963 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTDoseVisualizerControls.ui @@ -0,0 +1,514 @@ + + + RTDoseVisualizerControls + + + + 0 + 0 + 421 + 651 + + + + + 0 + 0 + + + + QmitkTemplate + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + Dose specific information: + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + true + + + 30 Gy + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + + + + + + + Number of fractions: + + + + + + + Prescribed dose [Gy]: + + + + + + + Use as reference dose + + + + + + + true + + + + + + + + + + + + + 0 + 0 + + + + Free iso lines: + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + 16777215 + 110 + + + + + 0 + 25 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add + + + + + + + Remove + + + + + + + + + + + + Global iso dose visualization: + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + + 0 + 0 + + + + + 65 + 0 + + + + Dose display: + + + + + + + + + + + 0 + 0 + + + + + 65 + 0 + + + + Preset style: + + + + + + + + 0 + 0 + + + + + 105 + 0 + + + + Qt::NoFocus + + + Reference dose [Gy]: + + + + + + + + + + 1 + + + 0.100000000000000 + + + 9999.000000000000000 + + + 0.100000000000000 + + + + + + + + + relative [%] + + + true + + + + + + + absolute [Gy] + + + + + + + + + + + false + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + 30 + 20 + + + + 80 + + + + + + + + + Global visibility: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Isolines + + + + :/RTUI/eye_open.png + + + + + 24 + 16 + + + + + + + + false + + + Colorwash + + + + :/RTUI/eye_open.png + + + + + 24 + 16 + + + + + + + + + + + + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + 255 + 0 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + 120 + 120 + 120 + + + + + + + + Convert node to dose node (for testing only!) + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.cpp new file mode 100644 index 0000000000..445efc1532 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.cpp @@ -0,0 +1,117 @@ +/*=================================================================== + +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 "RTUIPreferencePage.h" + +#include "mitkRTUIConstants.h" + +#include +#include + +//----------------------------------------------------------------------------- +RTUIPreferencePage::RTUIPreferencePage() + : m_MainControl(0), m_Controls(0) +{ + +} + + +//----------------------------------------------------------------------------- +RTUIPreferencePage::~RTUIPreferencePage() +{ + delete m_Controls; +} + + +//----------------------------------------------------------------------------- +void RTUIPreferencePage::Init(berry::IWorkbench::Pointer ) +{ + +} + + +//----------------------------------------------------------------------------- +void RTUIPreferencePage::CreateQtControl(QWidget* parent) +{ + berry::IPreferencesService::Pointer prefService + = berry::Platform::GetServiceRegistry() + .GetServiceById(berry::IPreferencesService::ID); + + m_PreferencesNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_PREFERENCE_NODE_ID); + + m_MainControl = new QWidget(parent); + m_Controls = new Ui::RTUIPreferencePageControls; + m_Controls->setupUi( m_MainControl ); + + connect(m_Controls->radioDefault, SIGNAL(toggled(bool)), m_Controls->spinDefault, SLOT(setEnabled(bool))); + connect(m_Controls->radioRelativeToMax, SIGNAL(toggled(bool)), m_Controls->spinRelativeToMax, SLOT(setEnabled(bool))); + + this->Update(); +} + + +//----------------------------------------------------------------------------- +QWidget* RTUIPreferencePage::GetQtControl() const +{ + return m_MainControl; +} + +//----------------------------------------------------------------------------- +bool RTUIPreferencePage::PerformOk() +{ + bool useAsDefaultValue = m_Controls->radioDefault->isChecked(); + m_PreferencesNode->PutBool(mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_AS_DEFAULT_ID,useAsDefaultValue); + + if (useAsDefaultValue) + { + m_PreferencesNode->PutDouble(mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE_ID, m_Controls->spinDefault->value()); + } + else + { + m_PreferencesNode->PutDouble(mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE_ID, m_Controls->spinRelativeToMax->value()/100.0); + } + + return true; +} + + +//----------------------------------------------------------------------------- +void RTUIPreferencePage::PerformCancel() +{ +} + + +//----------------------------------------------------------------------------- +void RTUIPreferencePage::Update() +{ + bool useAsDefaultValue = m_PreferencesNode->GetBool(mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_AS_DEFAULT_ID, true); + double doseValue = m_PreferencesNode->GetDouble(mitk::rt::UIConstants::UNKNOWN_PRESCRIBED_DOSE_HANDLING_VALUE_ID, 50.0); + + m_Controls->radioDefault->setChecked(useAsDefaultValue); + m_Controls->radioRelativeToMax->setChecked(!useAsDefaultValue); + m_Controls->spinDefault->setEnabled(useAsDefaultValue); + m_Controls->spinRelativeToMax->setEnabled(!useAsDefaultValue); + + if (useAsDefaultValue) + { + m_Controls->spinDefault->setValue(doseValue); + } + else + { + m_Controls->spinRelativeToMax->setValue(doseValue*100.0); + } +} diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.h new file mode 100644 index 0000000000..208a41773f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePage.h @@ -0,0 +1,85 @@ +/*=================================================================== + +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 __RT_UI_PREFERENCE_PAGE_H +#define __RT_UI_PREFERENCE_PAGE_H + +#include "berryIQtPreferencePage.h" +#include "berryIPreferences.h" + +#include "ui_RTUIPreferencePageControls.h" + +class QWidget; + +/** +* \class RTUIPreferencePage +* \brief Preference page for general RT visualization settings. +*/ +class RTUIPreferencePage : public QObject, public berry::IQtPreferencePage +{ + Q_OBJECT + Q_INTERFACES(berry::IPreferencePage) + +public: + RTUIPreferencePage(); + ~RTUIPreferencePage(); + + /** + * \brief Called by framework to initialize this preference page, but currently does nothing. + * \param workbench The workbench. + */ + void Init(berry::IWorkbench::Pointer workbench); + + /** + * \brief Called by framework to create the GUI, and connect signals and slots. + * \param widget The Qt widget that acts as parent to all GUI components, as this class itself is not derived from QWidget. + */ + void CreateQtControl(QWidget* widget); + + /** + * \brief Required by framework to get hold of the GUI. + * \return QWidget* the top most QWidget for the GUI. + */ + QWidget* GetQtControl() const; + + /** + * \see IPreferencePage::PerformOk + */ + virtual bool PerformOk(); + + /** + * \see IPreferencePage::PerformCancel + */ + virtual void PerformCancel(); + + /** + * \see IPreferencePage::Update + */ + virtual void Update(); + + public slots: + +protected: + + QWidget *m_MainControl; + Ui::RTUIPreferencePageControls* m_Controls; + + berry::IPreferences::Pointer m_PreferencesNode; + +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePageControls.ui b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePageControls.ui new file mode 100644 index 0000000000..efd18081ca --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/RTUIPreferencePageControls.ui @@ -0,0 +1,86 @@ + + + RTUIPreferencePageControls + + + + 0 + 0 + 403 + 438 + + + + Form + + + + + + Handling of unkown prescribed dose: + + + + + + false + + + % + + + 200.000000000000000 + + + 80.000000000000000 + + + + + + + set to default value: + + + + + + + set relative to max dose: + + + + + + + Gy + + + 9999.000000000000000 + + + 50.000000000000000 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.cpp new file mode 100644 index 0000000000..a8d01b1fd1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.cpp @@ -0,0 +1,245 @@ +/*=================================================================== + +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 "mitkDoseVisPreferenceHelper.h" +#include "mitkRTUIConstants.h" +#include "mitkIsoLevelsGenerator.h" + + +#include + +#include + +#include +#include + +void mitk::rt::StorePresetsMap(const PresetMapType& presetMap) +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer doseVisNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + berry::IPreferences::Pointer presetsNode = doseVisNode->Node(mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID); + + presetsNode->RemoveNode(); + doseVisNode->Flush(); + + //new empty preset node + presetsNode = doseVisNode->Node(mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID); + + //store map in new node + for (PresetMapType::const_iterator pos = presetMap.begin(); pos != presetMap.end(); ++pos) + { + berry::IPreferences::Pointer aPresetNode = presetsNode->Node(pos->first); + + unsigned int id = 0; + + for (mitk::IsoDoseLevelSet::ConstIterator levelPos = pos->second->Begin(); levelPos != pos->second->End(); ++levelPos, ++id ) + { + std::ostringstream stream; + stream << id; + + berry::IPreferences::Pointer levelNode = aPresetNode->Node(stream.str()); + + levelNode->PutDouble(mitk::rt::UIConstants::ISO_LEVEL_DOSE_VALUE_ID,levelPos->GetDoseValue()); + levelNode->PutFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_RED_ID,levelPos->GetColor().GetRed()); + levelNode->PutFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_GREEN_ID,levelPos->GetColor().GetGreen()); + levelNode->PutFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_BLUE_ID,levelPos->GetColor().GetBlue()); + levelNode->PutBool(mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_ISOLINES_ID,levelPos->GetVisibleIsoLine()); + levelNode->PutBool(mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_COLORWASH_ID,levelPos->GetVisibleColorWash()); + levelNode->Flush(); + } + + aPresetNode->Flush(); + } + + presetsNode->Flush(); +} + +mitk::rt::PresetMapType mitk::rt::LoadPresetsMap() +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer presetsNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID); + + typedef std::vector NamesType; + NamesType names = presetsNode->ChildrenNames(); + + PresetMapType presetMap; + + for (NamesType::const_iterator pos = names.begin(); pos != names.end(); ++pos) + { + berry::IPreferences::Pointer aPresetNode = presetsNode->Node(*pos); + + if (aPresetNode.IsNull()) + { + mitkThrow()<< "Error in preference interface. Cannot find preset node under given name. Name: "<<*pos; + } + + mitk::IsoDoseLevelSet::Pointer levelSet = mitk::IsoDoseLevelSet::New(); + + NamesType levelNames = aPresetNode->ChildrenNames(); + for (NamesType::const_iterator levelName = levelNames.begin(); levelName != levelNames.end(); ++levelName) + { + berry::IPreferences::Pointer levelNode = aPresetNode->Node(*levelName); + if (aPresetNode.IsNull()) + { + mitkThrow()<< "Error in preference interface. Cannot find level node under given preset name. Name: "<<*pos<<"; Level id: "<<*levelName; + } + + mitk::IsoDoseLevel::Pointer isoLevel = mitk::IsoDoseLevel::New(); + + isoLevel->SetDoseValue(levelNode->GetDouble(mitk::rt::UIConstants::ISO_LEVEL_DOSE_VALUE_ID,0.0)); + mitk::IsoDoseLevel::ColorType color; + color.SetRed(levelNode->GetFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_RED_ID,1.0)); + color.SetGreen(levelNode->GetFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_GREEN_ID,1.0)); + color.SetBlue(levelNode->GetFloat(mitk::rt::UIConstants::ISO_LEVEL_COLOR_BLUE_ID,1.0)); + isoLevel->SetColor(color); + isoLevel->SetVisibleIsoLine(levelNode->GetBool(mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_ISOLINES_ID,true)); + isoLevel->SetVisibleColorWash(levelNode->GetBool(mitk::rt::UIConstants::ISO_LEVEL_VISIBILITY_COLORWASH_ID,true)); + + levelSet->SetIsoDoseLevel(isoLevel); + } + + presetMap.insert(std::make_pair(*pos,levelSet)); + } + + if (presetMap.size() == 0) + { //if there are no presets use fallback and store it. + presetMap = mitk::rt::GenerateDefaultPresetsMap(); + StorePresetsMap(presetMap); + } + + return presetMap; +} + +mitk::rt::PresetMapType mitk::rt::GenerateDefaultPresetsMap() +{ + mitk::rt::PresetMapType result; + + result.insert(std::make_pair(std::string("Virtuos"), mitk::rt::GeneratIsoLevels_Virtuos())); + return result; +} + +std::string mitk::rt::GetSelectedPresetName() +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + std::string result = prefNode->Get(mitk::rt::UIConstants::SELECTED_ISO_PRESET_ID, ""); + + return result; +} + +void mitk::rt::SetSelectedPresetName(const std::string& presetName) +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + berry::IPreferences::Pointer presetsNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_ISO_PRESETS_PREFERENCE_NODE_ID); + + typedef std::vector NamesType; + NamesType presetNames = presetsNode->ChildrenNames(); + + NamesType::iterator finding = std::find(presetNames.begin(),presetNames.end(),presetName); + + if (finding == presetNames.end()) + { + mitkThrow()<< "Error. Tried to set invalid selected preset name. Preset name does not exist in the defined presets. Preset name: "<Put(mitk::rt::UIConstants::SELECTED_ISO_PRESET_ID,presetName); +} + +bool mitk::rt::GetReferenceDoseValue(mitk::DoseValueAbs& value) +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + bool result = prefNode->GetBool(mitk::rt::UIConstants::GLOBAL_REFERENCE_DOSE_SYNC_ID, true); + value = prefNode->GetDouble(mitk::rt::UIConstants::REFERENCE_DOSE_ID, mitk::rt::UIConstants::DEFAULT_REFERENCE_DOSE_VALUE); + + return result; +} + +void mitk::rt::SetReferenceDoseValue(bool globalSync, mitk::DoseValueAbs value) +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + prefNode->PutBool(mitk::rt::UIConstants::GLOBAL_REFERENCE_DOSE_SYNC_ID, globalSync); + if (value >= 0) + { + prefNode->PutDouble(mitk::rt::UIConstants::REFERENCE_DOSE_ID, value); + } +} + + +bool mitk::rt::GetDoseDisplayAbsolute() +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + bool result = prefNode->GetBool(mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID, false); + + return result; +} + +void mitk::rt::SetDoseDisplayAbsolute(bool isAbsolute) +{ + berry::IPreferencesService::Pointer prefService = + berry::Platform::GetServiceRegistry().GetServiceById(berry::IPreferencesService::ID); + + berry::IPreferences::Pointer prefNode = prefService->GetSystemPreferences()->Node(mitk::rt::UIConstants::ROOT_DOSE_VIS_PREFERENCE_NODE_ID); + + prefNode->PutBool(mitk::rt::UIConstants::DOSE_DISPLAY_ABSOLUTE_ID, isAbsolute); +} + +void mitk::rt::SignalReferenceDoseChange(bool globalSync, mitk::DoseValueAbs value, ctkPluginContext* context) +{ + ctkServiceReference ref = context->getServiceReference(); + if (ref) + { + ctkEventAdmin* eventAdmin = context->getService(ref); + ctkProperties props; + props["value"] = value; + props["globalSync"] = globalSync; + ctkEvent presetMapChangedEvent(mitk::rt::CTKEventConstants::TOPIC_REFERENCE_DOSE_CHANGED.c_str()); + eventAdmin->sendEvent(presetMapChangedEvent); + } +} + +void mitk::rt::SignalPresetMapChange(ctkPluginContext* context) +{ + ctkServiceReference ref = context->getServiceReference(); + if (ref) + { + ctkEventAdmin* eventAdmin = context->getService(ref); + ctkEvent presetMapChangedEvent(mitk::rt::CTKEventConstants::TOPIC_ISO_DOSE_LEVEL_PRESETS_CHANGED.c_str()); + eventAdmin->sendEvent(presetMapChangedEvent); + } +} diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.h new file mode 100644 index 0000000000..ebf9c734b4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/mitkDoseVisPreferenceHelper.h @@ -0,0 +1,74 @@ +/*=================================================================== + +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 __DOSE_VIS_PREFERENCE_HELPER_H +#define __DOSE_VIS_PREFERENCE_HELPER_H + +#include +#include + +#include "mitkIsoDoseLevelCollections.h" + +class ctkPluginContext; + +namespace mitk +{ + namespace rt + { + typedef std::map PresetMapType; + + /** Stores the given preset map in the application preferences. */ + void StorePresetsMap(const PresetMapType& presetMap); + + /** Loads all defined iso dose level presets from the preferences and stores them + in a map. Key is the name of the preset. + @remark If no presets are stored in the preferences this function will generate default presets + (using GenerateDefaultPresetsMap()) and the stores it in the preferences (to guarantee a consistent state) + before passing the default presets back.*/ + PresetMapType LoadPresetsMap(); + + /** Generate the default presets map.*/ + PresetMapType GenerateDefaultPresetsMap(); + + /**Retrieves the name of the preset, that is currently selected for the application, from the preferences.*/ + std::string GetSelectedPresetName(); + + /** checks if the passed name exists in the preset map. If not an exception is thrown. If it exists, the new + * value will be set.*/ + void SetSelectedPresetName(const std::string& presetName); + + /** retrieves the reference dose from the preferences and indicates if global sync for reference dose is activated + or not. + @param value The reference dose value stored in the preferences. + @return Indicator for global sync. True: global sync activated -> preference value is relevant. + False: global sync deactivated. Value is irrelevant. Each node has its own value.*/ + bool GetReferenceDoseValue(DoseValueAbs& value); + /** Sets the global sync setting and dose reference value in the preferences. + * @param globalSync Indicator if global sync should be set active (true) or inactive (false). If it is true, the value is irrelevant (but will be set). + * @param value The dose reference value that should be stored in the preferences.If set to <0 it will be ignored and not changed/set.*/ + void SetReferenceDoseValue(bool globalSync, DoseValueAbs value = -1); + + bool GetDoseDisplayAbsolute(); + void SetDoseDisplayAbsolute(bool isAbsolute); + + void SignalReferenceDoseChange(bool globalSync, mitk::DoseValueAbs value, ctkPluginContext* context); + void SignalPresetMapChange(ctkPluginContext* context); + + } +} + +#endif diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.cpp b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.cpp new file mode 100644 index 0000000000..eb0e2631cc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.cpp @@ -0,0 +1,55 @@ +/*=================================================================== + +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 "org_mitk_gui_qt_rt_dosevisualization_Activator.h" + +#include + +#include "RTDoseVisualizer.h" +#include "RTUIPreferencePage.h" +#include "DoseVisualizationPreferencePage.h" +#include "LoadingRTView.h" + +namespace mitk { + + ctkPluginContext* org_mitk_gui_qt_rt_dosevisualization_Activator::m_Context = NULL; + + void org_mitk_gui_qt_rt_dosevisualization_Activator::start(ctkPluginContext* context) + { + BERRY_REGISTER_EXTENSION_CLASS(RTDoseVisualizer, context); + BERRY_REGISTER_EXTENSION_CLASS(RTUIPreferencePage, context) + BERRY_REGISTER_EXTENSION_CLASS(DoseVisualizationPreferencePage, context) + BERRY_REGISTER_EXTENSION_CLASS(LoadingRTView, context) + + m_Context = context; + } + + void org_mitk_gui_qt_rt_dosevisualization_Activator::stop(ctkPluginContext* context) + { + Q_UNUSED(context); + + m_Context = NULL; + } + + ctkPluginContext* org_mitk_gui_qt_rt_dosevisualization_Activator::GetContext() + { + return m_Context; + } + +} + +Q_EXPORT_PLUGIN2(org_mitk_gui_qt_rt_dosevisualization, mitk::org_mitk_gui_qt_rt_dosevisualization_Activator) diff --git a/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.h b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.h new file mode 100644 index 0000000000..f0f1449354 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.rt.dosevisualization/src/internal/org_mitk_gui_qt_rt_dosevisualization_Activator.h @@ -0,0 +1,46 @@ +/*=================================================================== + +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_rt_dosevisualization_Activator_h +#define org_mitk_gui_qt_rt_dosevisualization_Activator_h + +#include + +namespace mitk { + + class org_mitk_gui_qt_rt_dosevisualization_Activator : + public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_INTERFACES(ctkPluginActivator) + + public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + + private: + + static ctkPluginContext* m_Context; + + }; // org_mitk_gui_qt_rt_dosevisualization_Activator + +} + +#endif // org_mitk_gui_qt_rt_dosevisualization_Activator_h