diff --git a/CMake/mitkMacroCreateModule.cmake b/CMake/mitkMacroCreateModule.cmake index 8a3a23afea..b9b7d3e481 100644 --- a/CMake/mitkMacroCreateModule.cmake +++ b/CMake/mitkMacroCreateModule.cmake @@ -1,374 +1,376 @@ ################################################################## # # MITK_CREATE_MODULE # #! Creates a module for the automatic module dependency system within MITK. #! Configurations are generated in the moduleConf directory. #! #! USAGE: #! #! \code #! MITK_CREATE_MODULE( #! [INCLUDE_DIRS ] #! [INTERNAL_INCLUDE_DIRS ] #! [DEPENDS ] #! [PACKAGE_DEPENDS ] #! [TARGET_DEPENDS #! [EXPORT_DEFINE ] #! [QT_MODULE] #! [HEADERS_ONLY] #! [WARNINGS_AS_ERRORS] #! \endcode #! #! \param MODULE_NAME_IN The name for the new module #! \param HEADERS_ONLY specify this if the modules just contains header files. ################################################################## macro(MITK_CREATE_MODULE MODULE_NAME_IN) set(_macro_params SUBPROJECTS # list of CDash labels VERSION # module version number, e.g. "1.2.0" INCLUDE_DIRS # exported include dirs (used in mitkMacroCreateModuleConf.cmake) INTERNAL_INCLUDE_DIRS # include dirs internal to this module DEPENDS # list of modules this module depends on DEPENDS_INTERNAL # list of modules this module internally depends on PACKAGE_DEPENDS # list of "packages this module depends on (e.g. Qt, VTK, etc.) TARGET_DEPENDS # list of CMake targets this module should depend on EXPORT_DEFINE # export macro name for public symbols of this module AUTOLOAD_WITH # a module target name identifying the module which will trigger the # automatic loading of this module ADDITIONAL_LIBS # list of addidtional libraries linked to this module GENERATED_CPP # not used (?) ) set(_macro_options QT_MODULE # the module makes use of Qt features and needs moc and ui generated files FORCE_STATIC # force building this module as a static library HEADERS_ONLY # this module is a headers-only library GCC_DEFAULT_VISIBILITY # do not use gcc visibility flags - all symbols will be exported NO_INIT # do not create CppMicroServices initialization code WARNINGS_AS_ERRORS # treat all compiler warnings as errors ) MACRO_PARSE_ARGUMENTS(MODULE "${_macro_params}" "${_macro_options}" ${ARGN}) set(MODULE_NAME ${MODULE_NAME_IN}) if(MODULE_HEADERS_ONLY) set(MODULE_PROVIDES ) if(MODULE_AUTOLOAD_WITH) message(SEND_ERROR "A headers only module cannot be auto-loaded") endif() else() set(MODULE_PROVIDES ${MODULE_NAME}) if(NOT MODULE_NO_INIT AND NOT MODULE_NAME STREQUAL "Mitk") # Add a dependency to the "Mitk" module list(APPEND MODULE_DEPENDS Mitk) endif() endif() if(NOT MODULE_SUBPROJECTS) if(MITK_DEFAULT_SUBPROJECTS) set(MODULE_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS}) endif() endif() # check if the subprojects exist as targets if(MODULE_SUBPROJECTS) foreach(subproject ${MODULE_SUBPROJECTS}) if(NOT TARGET ${subproject}) message(SEND_ERROR "The subproject ${subproject} does not have a corresponding target") endif() endforeach() endif() # check and set-up auto-loading if(MODULE_AUTOLOAD_WITH) if(NOT TARGET "${MODULE_AUTOLOAD_WITH}") message(SEND_ERROR "The module target \"${MODULE_AUTOLOAD_WITH}\" specified as the auto-loading module for \"${MODULE_NAME}\" does not exist") endif() # create a meta-target if it does not already exist set(_module_autoload_meta_target "${MODULE_AUTOLOAD_WITH}-universe") if(NOT TARGET ${_module_autoload_meta_target}) add_custom_target(${_module_autoload_meta_target}) endif() endif() # assume worst case set(MODULE_IS_ENABLED 0) # first we check if we have an explicit module build list if(MITK_MODULES_TO_BUILD) list(FIND MITK_MODULES_TO_BUILD ${MODULE_NAME} _MOD_INDEX) if(_MOD_INDEX EQUAL -1) set(MODULE_IS_EXCLUDED 1) endif() endif() if(NOT MODULE_IS_EXCLUDED AND NOT (MODULE_QT_MODULE AND NOT MITK_USE_QT)) # first of all we check for the dependencies MITK_CHECK_MODULE(_MISSING_DEP ${MODULE_DEPENDS}) if(_MISSING_DEP) message("Module ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}") set(MODULE_IS_ENABLED 0) else(_MISSING_DEP) set(MODULE_IS_ENABLED 1) # now check for every package if it is enabled. This overlaps a bit with # MITK_CHECK_MODULE ... foreach(_package ${MODULE_PACKAGE_DEPENDS}) if((DEFINED MITK_USE_${_package}) AND NOT (MITK_USE_${_package})) message("Module ${MODULE_NAME} won't be built. Turn on MITK_USE_${_package} if you want to use it.") set(MODULE_IS_ENABLED 0) endif() endforeach() if(MODULE_IS_ENABLED) # clear variables defined in files.cmake set(RESOURCE_FILES ) set(CPP_FILES ) set(H_FILES ) set(TXX_FILES ) set(DOX_FILES ) set(UI_FILES ) set(MOC_H_FILES ) set(QRC_FILES ) # clear other variables set(Q${KITNAME}_GENERATED_MOC_CPP ) set(Q${KITNAME}_GENERATED_QRC_CPP ) set(Q${KITNAME}_GENERATED_UI_CPP ) _MITK_CREATE_MODULE_CONF() if(NOT MODULE_EXPORT_DEFINE) set(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT) endif(NOT MODULE_EXPORT_DEFINE) if(MITK_GENERATE_MODULE_DOT) message("MODULEDOTNAME ${MODULE_NAME}") foreach(dep ${MODULE_DEPENDS}) message("MODULEDOT \"${MODULE_NAME}\" -> \"${dep}\" ; ") endforeach(dep) endif(MITK_GENERATE_MODULE_DOT) set(DEPENDS "${MODULE_DEPENDS}") set(DEPENDS_BEFORE "not initialized") set(PACKAGE_DEPENDS "${MODULE_PACKAGE_DEPENDS}") MITK_USE_MODULE("${MODULE_DEPENDS}") # ok, now create the module itself include_directories(. ${ALL_INCLUDE_DIRECTORIES}) include(files.cmake) set(module_compile_flags ) if(WIN32) set(module_compile_flags "${module_compile_flags} -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN") endif() if(MODULE_GCC_DEFAULT_VISIBILITY) set(use_visibility_flags 0) else() # We only support hidden visibility for gcc for now. Clang 3.0 still has troubles with # correctly marking template declarations and explicit template instantiations as exported. # See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028 # and http://llvm.org/bugs/show_bug.cgi?id=10113 if(CMAKE_COMPILER_IS_GNUCXX) set(use_visibility_flags 1) else() # set(use_visibility_flags 0) endif() endif() if(CMAKE_COMPILER_IS_GNUCXX) # MinGW does not export all symbols automatically, so no need to set flags. # # With gcc < 4.5, RTTI symbols from classes declared in third-party libraries # which are not "gcc visibility aware" are marked with hidden visibility in # DSOs which include the class declaration and which are compiled with # hidden visibility. This leads to dynamic_cast and exception handling problems. # While this problem could be worked around by sandwiching the include # directives for the third-party headers between "#pragma visibility push/pop" # statements, it is generally safer to just use default visibility with # gcc < 4.5. if(${GCC_VERSION} VERSION_LESS "4.5" OR MINGW) set(use_visibility_flags 0) endif() endif() if(use_visibility_flags) mitkFunctionCheckCompilerFlags("-fvisibility=hidden" module_compile_flags) mitkFunctionCheckCompilerFlags("-fvisibility-inlines-hidden" module_compile_flags) endif() configure_file(${MITK_SOURCE_DIR}/CMake/moduleExports.h.in ${CMAKE_BINARY_DIR}/${MODULES_CONF_DIRNAME}/${MODULE_NAME}Exports.h @ONLY) if(MODULE_WARNINGS_AS_ERRORS) if(MSVC_VERSION) mitkFunctionCheckCompilerFlags("/WX" module_compile_flags) else() mitkFunctionCheckCompilerFlags("-Werror" module_compile_flags) # The flag "c++0x-static-nonintegral-init" has been renamed in newer Clang # versions to "static-member-init", see # http://clang-developers.42468.n3.nabble.com/Wc-0x-static-nonintegral-init-gone-td3999651.html # # Also, older Clang and seemingly all gcc versions do not warn if unknown # "-no-*" flags are used, so CMake will happily append any -Wno-* flag to the # command line. This may get confusing if unrelated compiler errors happen and # the error output then additinally contains errors about unknown flags (which # is not the case if there were no compile errors). # # So instead of using -Wno-* we use -Wno-error=*, which will be properly rejected by # the compiler and if applicable, prints the specific warning as a real warning and # not as an error (although -Werror was given). mitkFunctionCheckCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" module_compile_flags) + mitkFunctionCheckCompilerFlags("-Wno-error=static-member-init" module_compile_flags) + mitkFunctionCheckCompilerFlags("-Wno-unknown-warning-option" module_compile_flags) mitkFunctionCheckCompilerFlags("-Wno-error=gnu" module_compile_flags) # VNL headers throw a lot of these, not fixable for us at least in ITK 3 mitkFunctionCheckCompilerFlags("-Wno-error=unused-parameter" module_compile_flags) # Some DICOM header file in ITK mitkFunctionCheckCompilerFlags("-Wno-error=cast-align" module_compile_flags) endif() endif(MODULE_WARNINGS_AS_ERRORS) if(MODULE_FORCE_STATIC) set(_STATIC STATIC) else() set(_STATIC ) endif(MODULE_FORCE_STATIC) if(NOT MODULE_NO_INIT) set(MODULE_LIBNAME ${MODULE_PROVIDES}) usFunctionGenerateModuleInit(CPP_FILES NAME ${MODULE_NAME} LIBRARY_NAME ${MODULE_LIBNAME} DEPENDS ${MODULE_DEPENDS} ${MODULE_DEPENDS_INTERNAL} ${MODULE_PACKAGE_DEPENDS} #VERSION ${MODULE_VERSION} ) if(RESOURCE_FILES) usFunctionEmbedResources(CPP_FILES LIBRARY_NAME ${MODULE_LIBNAME} ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Resources FILES ${RESOURCE_FILES}) endif() endif() if(MODULE_QT_MODULE) if(UI_FILES) QT4_WRAP_UI(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES}) endif(UI_FILES) if(MOC_H_FILES) QT4_WRAP_CPP(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES}) endif(MOC_H_FILES) if(QRC_FILES) QT4_ADD_RESOURCES(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES}) endif(QRC_FILES) set(Q${KITNAME}_GENERATED_CPP ${Q${KITNAME}_GENERATED_CPP} ${Q${KITNAME}_GENERATED_UI_CPP} ${Q${KITNAME}_GENERATED_MOC_CPP} ${Q${KITNAME}_GENERATED_QRC_CPP}) endif() ORGANIZE_SOURCES(SOURCE ${CPP_FILES} HEADER ${H_FILES} TXX ${TXX_FILES} DOC ${DOX_FILES} UI ${UI_FILES} QRC ${QRC_FILES} MOC ${Q${KITNAME}_GENERATED_MOC_CPP} GEN_QRC ${Q${KITNAME}_GENERATED_QRC_CPP} GEN_UI ${Q${KITNAME}_GENERATED_UI_CPP}) set(coverage_sources ${CPP_FILES} ${H_FILES} ${GLOBBED__H_FILES} ${CORRESPONDING__H_FILES} ${TXX_FILES} ${TOOL_CPPS} ${TOOL_GUI_CPPS}) if(MODULE_SUBPROJECTS) set_property(SOURCE ${coverage_sources} APPEND PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK) endif() if(NOT MODULE_HEADERS_ONLY) if(ALL_LIBRARY_DIRS) # LINK_DIRECTORIES applies only to targets which are added after the call to LINK_DIRECTORIES link_directories(${ALL_LIBRARY_DIRS}) endif(ALL_LIBRARY_DIRS) add_library(${MODULE_PROVIDES} ${_STATIC} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP} ${DOX_FILES} ${UI_FILES} ${QRC_FILES}) if(MODULE_TARGET_DEPENDS) add_dependencies(${MODULE_PROVIDES} ${MODULE_TARGET_DEPENDS}) endif() if(MODULE_SUBPROJECTS) set_property(TARGET ${MODULE_PROVIDES} PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK) foreach(subproject ${MODULE_SUBPROJECTS}) add_dependencies(${subproject} ${MODULE_PROVIDES}) endforeach() endif() if(ALL_LIBRARIES) target_link_libraries(${MODULE_PROVIDES} ${ALL_LIBRARIES}) endif(ALL_LIBRARIES) if(MODULE_QT_MODULE AND QT_LIBRARIES) target_link_libraries(${MODULE_PROVIDES} ${QT_LIBRARIES}) endif() if(MINGW) target_link_libraries(${MODULE_PROVIDES} ssp) # add stack smash protection lib endif() # Apply properties to the module target. set_target_properties(${MODULE_PROVIDES} PROPERTIES COMPILE_FLAGS "${module_compile_flags}") # add the target name to a global property which is used in the top-level # CMakeLists.txt file to export the target set_property(GLOBAL APPEND PROPERTY MITK_MODULE_TARGETS ${MODULE_PROVIDES}) if(MODULE_AUTOLOAD_WITH) # for auto-loaded modules, adapt the output directory add_dependencies(${_module_autoload_meta_target} ${MODULE_PROVIDES}) if(WIN32) set(_module_output_prop RUNTIME_OUTPUT_DIRECTORY) else() set(_module_output_prop LIBRARY_OUTPUT_DIRECTORY) endif() set(_module_output_dir ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH}) get_target_property(_module_is_imported ${MODULE_AUTOLOAD_WITH} IMPORTED) if(NOT _module_is_imported) # if the auto-loading module is not imported, get its location # and put the auto-load module relative to it. get_target_property(_module_output_dir ${MODULE_AUTOLOAD_WITH} ${_module_output_prop}) set_target_properties(${MODULE_PROVIDES} PROPERTIES ${_module_output_prop} ${_module_output_dir}/${MODULE_AUTOLOAD_WITH}) else() set_target_properties(${MODULE_PROVIDES} PROPERTIES ${_module_output_prop} ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH}) endif() set_target_properties(${MODULE_PROVIDES} PROPERTIES MITK_AUTOLOAD_DIRECTORY ${MODULE_AUTOLOAD_WITH}) # add the auto-load module name as a property set_property(TARGET ${MODULE_AUTOLOAD_WITH} APPEND PROPERTY MITK_AUTOLOAD_TARGETS ${MODULE_PROVIDES}) else() # Add meta dependencies (e.g. on auto-load modules from depending modules) if(ALL_META_DEPENDENCIES) add_dependencies(${MODULE_PROVIDES} ${ALL_META_DEPENDENCIES}) endif() endif() endif() endif(MODULE_IS_ENABLED) endif(_MISSING_DEP) endif(NOT MODULE_IS_EXCLUDED AND NOT (MODULE_QT_MODULE AND NOT MITK_USE_QT)) if(NOT MODULE_IS_ENABLED) _MITK_CREATE_MODULE_CONF() endif(NOT MODULE_IS_ENABLED) endmacro(MITK_CREATE_MODULE) diff --git a/Core/Code/Algorithms/mitkPlaneClipping.h b/Core/Code/Algorithms/mitkPlaneClipping.h index 1d7da8505b..f685f5589a 100644 --- a/Core/Code/Algorithms/mitkPlaneClipping.h +++ b/Core/Code/Algorithms/mitkPlaneClipping.h @@ -1,141 +1,141 @@ /*=================================================================== 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 MITKPLANECLIPPING_H_HEADER_INCLUDED #define MITKPLANECLIPPING_H_HEADER_INCLUDED #include #include #include #include namespace mitk { namespace PlaneClipping { /** \brief Internal helper method for intersection testing used only in CalculateClippedPlaneBounds() */ static bool LineIntersectZero( vtkPoints *points, int p1, int p2, vtkFloatingPointType *bounds ) { vtkFloatingPointType point1[3]; vtkFloatingPointType point2[3]; points->GetPoint( p1, point1 ); points->GetPoint( p2, point2 ); if ( (point1[2] * point2[2] <= 0.0) && (point1[2] != point2[2]) ) { double x, y; x = ( point1[0] * point2[2] - point1[2] * point2[0] ) / ( point2[2] - point1[2] ); y = ( point1[1] * point2[2] - point1[2] * point2[1] ) / ( point2[2] - point1[2] ); if ( x < bounds[0] ) { bounds[0] = x; } if ( x > bounds[1] ) { bounds[1] = x; } if ( y < bounds[2] ) { bounds[2] = y; } if ( y > bounds[3] ) { bounds[3] = y; } bounds[4] = bounds[5] = 0.0; return true; } return false; } /** \brief Calculate the bounding box of the resliced image. This is necessary for arbitrarily rotated planes in an image volume. A rotated plane (e.g. in swivel mode) will have a new bounding box, which needs to be calculated. */ static bool CalculateClippedPlaneBounds( const Geometry3D *boundingGeometry, const PlaneGeometry *planeGeometry, vtkFloatingPointType *bounds ) { // Clip the plane with the bounding geometry. To do so, the corner points // of the bounding box are transformed by the inverse transformation // matrix, and the transformed bounding box edges derived therefrom are // clipped with the plane z=0. The resulting min/max values are taken as // bounds for the image reslicer. const mitk::BoundingBox *boundingBox = boundingGeometry->GetBoundingBox(); mitk::BoundingBox::PointType bbMin = boundingBox->GetMinimum(); mitk::BoundingBox::PointType bbMax = boundingBox->GetMaximum(); vtkSmartPointer points = vtkSmartPointer::New(); if(boundingGeometry->GetImageGeometry()) { points->InsertPoint( 0, bbMin[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 ); points->InsertPoint( 1, bbMin[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 ); points->InsertPoint( 2, bbMin[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 ); points->InsertPoint( 3, bbMin[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 ); points->InsertPoint( 4, bbMax[0]-0.5, bbMin[1]-0.5, bbMin[2]-0.5 ); points->InsertPoint( 5, bbMax[0]-0.5, bbMin[1]-0.5, bbMax[2]-0.5 ); points->InsertPoint( 6, bbMax[0]-0.5, bbMax[1]-0.5, bbMax[2]-0.5 ); points->InsertPoint( 7, bbMax[0]-0.5, bbMax[1]-0.5, bbMin[2]-0.5 ); } else { points->InsertPoint( 0, bbMin[0], bbMin[1], bbMin[2] ); points->InsertPoint( 1, bbMin[0], bbMin[1], bbMax[2] ); points->InsertPoint( 2, bbMin[0], bbMax[1], bbMax[2] ); points->InsertPoint( 3, bbMin[0], bbMax[1], bbMin[2] ); points->InsertPoint( 4, bbMax[0], bbMin[1], bbMin[2] ); points->InsertPoint( 5, bbMax[0], bbMin[1], bbMax[2] ); points->InsertPoint( 6, bbMax[0], bbMax[1], bbMax[2] ); points->InsertPoint( 7, bbMax[0], bbMax[1], bbMin[2] ); } vtkSmartPointer newPoints = vtkSmartPointer::New(); vtkSmartPointer transform = vtkSmartPointer::New(); transform->Identity(); transform->Concatenate( planeGeometry->GetVtkTransform()->GetLinearInverse() ); transform->Concatenate( boundingGeometry->GetVtkTransform() ); transform->TransformPoints( points, newPoints ); bounds[0] = bounds[2] = 10000000.0; bounds[1] = bounds[3] = -10000000.0; bounds[4] = bounds[5] = 0.0; LineIntersectZero( newPoints, 0, 1, bounds ); LineIntersectZero( newPoints, 1, 2, bounds ); LineIntersectZero( newPoints, 2, 3, bounds ); LineIntersectZero( newPoints, 3, 0, bounds ); LineIntersectZero( newPoints, 0, 4, bounds ); LineIntersectZero( newPoints, 1, 5, bounds ); LineIntersectZero( newPoints, 2, 6, bounds ); LineIntersectZero( newPoints, 3, 7, bounds ); LineIntersectZero( newPoints, 4, 5, bounds ); LineIntersectZero( newPoints, 5, 6, bounds ); LineIntersectZero( newPoints, 6, 7, bounds ); LineIntersectZero( newPoints, 7, 4, bounds ); if ( (bounds[0] > 9999999.0) || (bounds[2] > 9999999.0) || (bounds[1] < -9999999.0) || (bounds[3] < -9999999.0) ) { return false; } else { // The resulting bounds must be adjusted by the plane spacing, since we // we have so far dealt with index coordinates const float *planeSpacing = planeGeometry->GetFloatSpacing(); bounds[0] *= planeSpacing[0]; bounds[1] *= planeSpacing[0]; bounds[2] *= planeSpacing[1]; bounds[3] *= planeSpacing[1]; bounds[4] *= planeSpacing[2]; bounds[5] *= planeSpacing[2]; return true; } } } } -#endif \ No newline at end of file +#endif diff --git a/Core/Code/Interactions/mitkBindDispatcherInteractor.cpp b/Core/Code/Interactions/mitkBindDispatcherInteractor.cpp index cc8c0f0189..8ac1a5453c 100644 --- a/Core/Code/Interactions/mitkBindDispatcherInteractor.cpp +++ b/Core/Code/Interactions/mitkBindDispatcherInteractor.cpp @@ -1,111 +1,110 @@ /*=================================================================== 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 "mitkBindDispatcherInteractor.h" #include "mitkMessage.h" #include // us #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" -//#include "mitkInformer.h" mitk::BindDispatcherInteractor::BindDispatcherInteractor() : - m_DataStorage(NULL),m_InformerService(NULL) + m_DataStorage(NULL) { ModuleContext* context = ModuleRegistry::GetModule(1)->GetModuleContext(); if (context == NULL) { MITK_ERROR<< "BindDispatcherInteractor() - Context could not be obtained."; return; } m_Dispatcher = Dispatcher::New(); } void mitk::BindDispatcherInteractor::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { // Set/Change Datastorage. This registers BDI to listen for events of DataStorage, to be informed when // a DataNode with a Interactor is added/modified/removed. // clean up events from previous datastorage UnRegisterDataStorageEvents(); m_DataStorage = dataStorage; RegisterDataStorageEvents(); } mitk::BindDispatcherInteractor::~BindDispatcherInteractor() { if (m_DataStorage.IsNotNull()) { UnRegisterDataStorageEvents(); } } void mitk::BindDispatcherInteractor::RegisterInteractor(const mitk::DataNode* dataNode) { if (m_Dispatcher.IsNotNull()) { m_Dispatcher->AddDataInteractor(dataNode); } } void mitk::BindDispatcherInteractor::RegisterDataStorageEvents() { if (m_DataStorage.IsNotNull()) { m_DataStorage->AddNodeEvent.AddListener( MessageDelegate1(this, &BindDispatcherInteractor::RegisterInteractor)); m_DataStorage->RemoveNodeEvent.AddListener( MessageDelegate1(this, &BindDispatcherInteractor::UnRegisterInteractor)); m_DataStorage->ChangedNodeEvent.AddListener( MessageDelegate1(this, &BindDispatcherInteractor::RegisterInteractor)); } } void mitk::BindDispatcherInteractor::UnRegisterInteractor(const DataNode* dataNode) { if (m_Dispatcher.IsNotNull()) { m_Dispatcher->RemoveDataInteractor(dataNode); } } const mitk::Dispatcher::Pointer mitk::BindDispatcherInteractor::GetDispatcher() { return m_Dispatcher; } void mitk::BindDispatcherInteractor::SetDispatcher(Dispatcher::Pointer dispatcher) { m_Dispatcher = dispatcher; } void mitk::BindDispatcherInteractor::UnRegisterDataStorageEvents() { if (m_DataStorage.IsNotNull()) { m_DataStorage->AddNodeEvent.RemoveListener( MessageDelegate1(this, &BindDispatcherInteractor::RegisterInteractor)); m_DataStorage->RemoveNodeEvent.RemoveListener( MessageDelegate1(this, &BindDispatcherInteractor::UnRegisterInteractor)); m_DataStorage->ChangedNodeEvent.RemoveListener( MessageDelegate1(this, &BindDispatcherInteractor::RegisterInteractor)); } } diff --git a/Core/Code/Interactions/mitkBindDispatcherInteractor.h b/Core/Code/Interactions/mitkBindDispatcherInteractor.h index 87e1571fc2..b3dc084895 100644 --- a/Core/Code/Interactions/mitkBindDispatcherInteractor.h +++ b/Core/Code/Interactions/mitkBindDispatcherInteractor.h @@ -1,82 +1,80 @@ /*=================================================================== 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 mitkBindDispatcherInteractor_h #define mitkBindDispatcherInteractor_h #include "mitkCommon.h" #include #include "mitkDataStorage.h" #include "mitkDataNode.h" #include "mitkDispatcher.h" namespace mitk { - class InformerService; /** * \class BindDispatcherInteractor * \brief This Class is used to connect a DataStorage with the Dispatcher. * * This is done by registering for DataStorage Events and sending the Events to the registered Dispatcher. * When a DataInteractor is registered with a DataNode the Dispatcher will be notified. * Also this class registers the MicroService at which InteractionEventObservers can register to receive events. * * \ingroup Interaction */ class MITK_CORE_EXPORT BindDispatcherInteractor { public: BindDispatcherInteractor(); ~BindDispatcherInteractor(); /** * Sets the DataStorage to which Events the class subscribes. */ void SetDataStorage(DataStorage::Pointer dataStorage); /** * Sets Dispatcher which will be notified. By default each RenderWindow gets its own Dispatcher, * this function can be used to override this behavior. */ void SetDispatcher(Dispatcher::Pointer dispatcher); /** * Return currently active Dispatcher. */ const Dispatcher::Pointer GetDispatcher(); private: /** @brief Registers for events from DataStorage. * * This way whenever a DataNode is added the Dispatcher is notified about this change, and checks whether a DataInteractor * is set for this DataNode */ void RegisterInteractor(const DataNode* dataNode); void UnRegisterInteractor(const DataNode* dataNode); void RegisterDataStorageEvents(); void UnRegisterDataStorageEvents(); Dispatcher::Pointer m_Dispatcher; DataStorage::Pointer m_DataStorage; - InformerService* m_InformerService; // holds reference to MicroService that notifies listeners }; } #endif /* mitkBindDispatcherInteractor_h */ diff --git a/Core/Code/Interactions/mitkStateMachineFactory.cpp b/Core/Code/Interactions/mitkStateMachineFactory.cpp index 29da306c5d..68c855cb0d 100755 --- a/Core/Code/Interactions/mitkStateMachineFactory.cpp +++ b/Core/Code/Interactions/mitkStateMachineFactory.cpp @@ -1,468 +1,478 @@ /*=================================================================== - The Medical Imaging Interaction Toolkit (MITK) +The Medical Imaging Interaction Toolkit (MITK) - Copyright (c) German Cancer Research Center, - Division of Medical and Biological Informatics. - All rights reserved. +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. +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. +See LICENSE.txt or http://www.mitk.org for details. - ===================================================================*/ +===================================================================*/ #include "mitkStateMachineFactory.h" #include "mitkGlobalInteraction.h" #include #include #include #include #include // us #include "mitkModule.h" #include "mitkModuleResource.h" #include "mitkModuleResourceStream.h" #include "mitkModuleRegistry.h" /** * @brief This class builds up all the necessary structures for a statemachine. * and stores one start-state for all built statemachines. **/ //mitk::StateMachineFactory::StartStateMap mitk::StateMachineFactory::m_StartStates; //mitk::StateMachineFactory::AllStateMachineMapType mitk::StateMachineFactory::m_AllStateMachineMap; //std::string mitk::StateMachineFactory::s_LastLoadedBehavior; + //XML StateMachine const std::string STYLE = "STYLE"; const std::string NAME = "NAME"; const std::string ID = "ID"; const std::string START_STATE = "START_STATE"; const std::string NEXT_STATE_ID = "NEXT_STATE_ID"; const std::string EVENT_ID = "EVENT_ID"; const std::string SIDE_EFFECT_ID = "SIDE_EFFECT_ID"; const std::string ISTRUE = "TRUE"; const std::string ISFALSE = "FALSE"; const std::string CONFIG = "stateMachine"; const std::string STATE = "state"; const std::string TRANSITION = "transition"; const std::string STATE_MACHINE_NAME = "stateMachine"; const std::string ACTION = "action"; const std::string BOOL_PARAMETER = "boolParameter"; const std::string INT_PARAMETER = "intParameter"; const std::string FLOAT_PARAMETER = "floatParameter"; const std::string DOUBLE_PARAMETER = "doubleParameter"; const std::string STRING_PARAMETER = "stringParameter"; const std::string VALUE = "VALUE"; #include namespace mitk { vtkStandardNewMacro(StateMachineFactory); } -mitk::StateMachineFactory::StateMachineFactory() : - m_AktStateMachineName(""), m_SkipStateMachine(false) +mitk::StateMachineFactory::StateMachineFactory() + : m_AktTransition(NULL) + , m_AktStateMachineName("") + , m_SkipStateMachine(false) { } mitk::StateMachineFactory::~StateMachineFactory() { //free memory while (!m_AllStateMachineMap.empty()) { StateMachineMapType* temp = m_AllStateMachineMap.begin()->second; m_AllStateMachineMap.erase(m_AllStateMachineMap.begin()); delete temp; } //should not be necessary due to SmartPointers m_StartStates.clear(); - - //delete WeakPointer - if (m_AktTransition) - delete m_AktTransition; } + /** * @brief Returns NULL if no entry with string type is found. **/ mitk::State* mitk::StateMachineFactory::GetStartState(const char * type) { StartStateMapIter tempState = m_StartStates.find(type); if (tempState != m_StartStates.end()) return (tempState)->second.GetPointer(); MITK_ERROR<< "Error in StateMachineFactory: StartState for pattern \""<< type<< "\"not found! StateMachine might not work!\n"; return NULL; } /** * @brief Loads the xml file filename and generates the necessary instances. **/ bool mitk::StateMachineFactory::LoadBehavior(std::string fileName) { if (fileName.empty()) return false; m_LastLoadedBehavior = fileName; this->SetFileName(fileName.c_str()); return this->Parse(); } /** * @brief Loads the xml string and generates the necessary instances. **/ bool mitk::StateMachineFactory::LoadBehaviorString(std::string xmlString) { if (xmlString.empty()) return false; m_LastLoadedBehavior = "String"; return (this->Parse(xmlString.c_str(), (unsigned int) xmlString.length())); } bool mitk::StateMachineFactory::LoadStandardBehavior() { Module* module = ModuleRegistry::GetModule("Mitk"); ModuleResource resource = module->GetResource("Interactions/Legacy/StateMachine.xml"); if (!resource.IsValid()) { mitkThrow()<< ("Resource not valid. State machine pattern not found:Interactions/Legacy/StateMachine.xml" ); } mitk::ModuleResourceStream stream(resource); std::string patternString((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); return this->LoadBehaviorString(patternString); } /** * @brief Recursive method, that parses this brand of * the stateMachine; if the history has the same * size at the end, then the StateMachine is correct **/ bool mitk::StateMachineFactory::RParse(mitk::State::StateMap* states, mitk::State::StateMapIter thisState, HistorySet *history) { history->insert((thisState->second)->GetId()); //log our path //or thisState->first. but this seems safer std::set nextStatesSet = (thisState->second)->GetAllNextStates(); //remove loops in nextStatesSet; //nether do we have to go there, nor will it clear a deadlock std::set::iterator position = nextStatesSet.find((thisState->second)->GetId()); //look for the same state in nextStateSet if (position != nextStatesSet.end()) { //found the same state we are in! nextStatesSet.erase(position); //delete it, cause, we don't have to go there a second time! } //nextStatesSet is empty, so deadlock! if (nextStatesSet.empty()) { MITK_INFO<::iterator i = nextStatesSet.begin(); i != nextStatesSet.end(); i++) { if (history->find(*i) == history->end()) //if we haven't been in this nextstate { mitk::State::StateMapIter nextState = states->find(*i); //search the iterator for our nextState if (nextState == states->end()) { MITK_INFO<size() > 1) //only one state; don't have to be parsed for deadlocks! { //parse all the given states an check for deadlock or not connected states HistorySet *history = new HistorySet; mitk::State::StateMapIter firstState = states->begin(); //parse through all the given states, log the parsed elements in history bool ok = RParse(states, firstState, history); if ((states->size() == history->size()) && ok) { delete history; } else //ether !ok or sizeA!=sizeB { delete history; MITK_INFO<begin(); tempState != states->end(); tempState++) { //searched through the States and Connects all Transitions bool tempbool = ( ( tempState->second )->ConnectTransitions( states ) ); if ( tempbool == false ) { MITK_INFO< ok = m_AllStatesOfOneStateMachine.insert(mitk::State::StateMap::value_type(id , m_AktState)); if ( ok.second == false ) { MITK_INFO<AddTransition( m_AktTransition ); + { + mitk::Transition* transition = new Transition(transitionName, nextStateId, eventId); + if (!m_AktState->AddTransition( transition )) + { + delete transition; + m_AktTransition = const_cast(m_AktState->GetTransition(eventId)); + } + else + { + m_AktTransition = transition; + } + } } - else if ( name == ACTION ) + else if ( name == ACTION && m_AktTransition) { int actionId = ReadXMLIntegerAttribut( ID, atts ); m_AktAction = Action::New( actionId ); m_AktTransition->AddAction( m_AktAction ); } else if ( name == BOOL_PARAMETER ) { if ( !m_AktAction ) return; bool value = ReadXMLBooleanAttribut( VALUE, atts ); std::string name = ReadXMLStringAttribut( NAME, atts ); m_AktAction->AddProperty( name.c_str(), BoolProperty::New( value ) ); } else if ( name == INT_PARAMETER ) { if ( !m_AktAction ) return; int value = ReadXMLIntegerAttribut( VALUE, atts ); std::string name = ReadXMLStringAttribut( NAME, atts ); m_AktAction->AddProperty( name.c_str(), IntProperty::New( value ) ); } else if ( name == FLOAT_PARAMETER ) { if ( !m_AktAction ) return; float value = ReadXMLIntegerAttribut( VALUE, atts ); std::string name = ReadXMLStringAttribut( NAME, atts ); m_AktAction->AddProperty( name.c_str(), FloatProperty::New( value ) ); } else if ( name == DOUBLE_PARAMETER ) { if ( !m_AktAction ) return; double value = ReadXMLDoubleAttribut( VALUE, atts ); std::string name = ReadXMLStringAttribut( NAME, atts ); m_AktAction->AddProperty( name.c_str(), DoubleProperty::New( value ) ); } else if ( name == STRING_PARAMETER ) { if ( !m_AktAction ) return; std::string value = ReadXMLStringAttribut( VALUE, atts ); std::string name = ReadXMLStringAttribut( NAME, atts ); m_AktAction->AddProperty( name.c_str(), StringProperty::New( value ) ); } } void mitk::StateMachineFactory::EndElement(const char* elementName) { //bool ok = true; std::string name(elementName); //skip the state machine pattern because the name was not unique! if (m_SkipStateMachine && (name != CONFIG)) return; if (name == STATE_MACHINE_NAME) { if (m_SkipStateMachine) { m_SkipStateMachine = false; return; } /*ok =*/ConnectStates(&m_AllStatesOfOneStateMachine); m_AllStatesOfOneStateMachine.clear(); } else if (name == CONFIG) { //doesn't have to be done } else if (name == TRANSITION) { m_AktTransition = NULL; //pointer stored in its state. memory will be freed in destructor of class state } else if (name == ACTION) { m_AktAction = NULL; } else if (name == STATE) { m_AktState = NULL; } } std::string mitk::StateMachineFactory::ReadXMLStringAttribut(std::string name, const char** atts) { if (atts) { const char** attsIter = atts; while (*attsIter) { if (name == *attsIter) { attsIter++; return *attsIter; } attsIter++; attsIter++; } } return std::string(); } int mitk::StateMachineFactory::ReadXMLIntegerAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); return atoi(s.c_str()); } float mitk::StateMachineFactory::ReadXMLFloatAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); return (float) atof(s.c_str()); } double mitk::StateMachineFactory::ReadXMLDoubleAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); return atof(s.c_str()); } bool mitk::StateMachineFactory::ReadXMLBooleanAttribut(std::string name, const char** atts) { std::string s = ReadXMLStringAttribut(name, atts); if (s == ISTRUE) return true; else return false; } mitk::State* mitk::StateMachineFactory::GetState(const char * type, int StateId) { //check if the state exists AllStateMachineMapType::iterator i = m_AllStateMachineMap.find(type); if (i == m_AllStateMachineMap.end()) return NULL; //get the statemachine of the state StateMachineMapType* sm = m_AllStateMachineMap[type]; //get the state from its statemachine if (sm != NULL) return (*sm)[StateId].GetPointer(); else return NULL; } bool mitk::StateMachineFactory::AddStateMachinePattern(const char * type, mitk::State* startState, mitk::StateMachineFactory::StateMachineMapType* allStatesOfStateMachine) { if (startState == NULL || allStatesOfStateMachine == NULL) return false; //check if the pattern has already been added StartStateMapIter tempState = m_StartStates.find(type); if (tempState != m_StartStates.end()) { MITK_WARN<< "Pattern " << type << " has already been added!\n"; return false; } //add the start state m_StartStates.insert(StartStateMap::value_type(type, startState)); //add all states of the new pattern to hold their references m_AllStateMachineMap.insert(AllStateMachineMapType::value_type(type, allStatesOfStateMachine)); return true; } diff --git a/Core/Code/Interactions/mitkStateMachineFactory.h b/Core/Code/Interactions/mitkStateMachineFactory.h index 9840a80224..2ee96d0d4f 100755 --- a/Core/Code/Interactions/mitkStateMachineFactory.h +++ b/Core/Code/Interactions/mitkStateMachineFactory.h @@ -1,232 +1,232 @@ /*=================================================================== 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 STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD #define STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD #include #include "mitkState.h" #include "mitkTransition.h" #include "mitkAction.h" #include #include #include namespace mitk { /** *@brief builds up all specifiyed statemachines and hold them for later access * * According to the XML-File every different statemachine is build up. A new * instance of a new StateMachine grabs a StartState of one certain * state machine. Two instances of one kind of state machine share that * state machine. * During buildprocess at runtime each state machine is parsed for well formed style. * Currently different interaction styles are not yet supported. * To add individual state machine patterns, call LoadBehavior(...) * and it will be parsed added to the internal list of patterns * * @ingroup Interaction **/ /** * \deprecatedSince{2013_03} StateMachineFactory is deprecated. Please use mitk::StateMachineContainer instead. * Refer to \see DataInteractionPage for general information about the concept of the new implementation. */ class MITK_CORE_EXPORT StateMachineFactory : public vtkXMLParser { public: static StateMachineFactory *New(); vtkTypeMacro(StateMachineFactory,vtkXMLParser); /** * @brief Typedef for all states that are defined as start-states **/ typedef std::map StartStateMap; typedef StartStateMap::iterator StartStateMapIter; /** * @brief Typedef to be used for parsing all states of one statemachine **/ typedef std::set HistorySet; typedef HistorySet::iterator HistorySetIter; /** * @brief This type holds all states of one statemachine. **/ typedef std::map StateMachineMapType; /** * @brief this type holds all states of all statemachines so that a specific state can be accessed for persistence **/ typedef std::map AllStateMachineMapType; /** * @brief Returns the StartState of the StateMachine with the name type; * * Returns NULL if no entry with name type is found. * Here a Smartpointer is returned to ensure, that StateMachines are also considered during reference counting. **/ State* GetStartState(const char* type); /** * @brief loads the xml file filename and generates the necessary instances **/ bool LoadBehavior(std::string fileName); /** * @brief loads the xml string and generates the necessary instances **/ bool LoadBehaviorString(std::string xmlString); /** * @brief Try to load standard behavior file "StateMachine.xml" * * Search strategy: * \li try environment variable "MITKCONF" (path to "StateMachine.xml") * \li try "./StateMachine.xml" * \li try via source directory (using MITKROOT from cmake-created * mitkConfig.h) "MITKROOT/Interactions/mitkBaseInteraction/StateMachine.xml" **/ bool LoadStandardBehavior(); const std::string& GetLastLoadedBehavior() { return m_LastLoadedBehavior; } /** * @brief Adds the given pattern to the internal list of patterns * * Method to support addition of externaly loaded patterns. * Instances of states, transitions and actions are maintained within this class and freed on destruction. * The states already have to be connected by transitions and actions and checked for errors. * @params type name of the pattern to add. Will be used during initialization of a new interactor. * @params startState the start state of this pattern. * @params allStatesOfStateMachine a map of state ids and its states to hold their reference and delete them in destructor **/ bool AddStateMachinePattern(const char * type, mitk::State* startState, StateMachineMapType* allStatesOfStateMachine); /** * brief To enable StateMachine to access states **/ friend class StateMachine; protected: /** * @brief Default Constructor **/ StateMachineFactory(); /** * @brief Default Destructor **/ ~StateMachineFactory(); /** * @brief Derived from XMLReader **/ void StartElement (const char* elementName, const char **atts); /** * @brief Derived from XMLReader **/ void EndElement (const char* elementName); private: /** * @brief Derived from XMLReader **/ std::string ReadXMLStringAttribut( std::string name, const char** atts); /** * @brief Derived from XMLReader **/ float ReadXMLFloatAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ double ReadXMLDoubleAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ int ReadXMLIntegerAttribut( std::string name, const char** atts ); /** * @brief Derived from XMLReader **/ bool ReadXMLBooleanAttribut( std::string name, const char** atts ); /** * @brief Returns a Pointer to the desired state if found. **/ mitk::State* GetState( const char* type, int StateId ); /** * @brief Sets the pointers in Transition (setNextState(..)) according to the extracted xml-file content **/ bool ConnectStates(mitk::State::StateMap* states); /** * @brief Recusive method, that parses this pattern of the stateMachine and returns true if correct **/ bool RParse(mitk::State::StateMap* states, mitk::State::StateMapIter thisState, HistorySet *history); /** * @brief Holds all created States that are defined as StartState **/ StartStateMap m_StartStates; /** * @brief Holds all States of one StateMachine to build up the pattern. **/ mitk::State::StateMap m_AllStatesOfOneStateMachine; /** * @brief A pointer to a State to help building up the pattern **/ State::Pointer m_AktState; /** * @brief A pointer to a Transition to help building up the pattern **/ - itk::WeakPointer m_AktTransition; + Transition* m_AktTransition; /** * @brief A pointer to an Action to help building up the pattern **/ Action::Pointer m_AktAction; /** * @brief map to hold all statemachines to call GetState for friends **/ AllStateMachineMapType m_AllStateMachineMap; std::string m_LastLoadedBehavior; std::string m_AktStateMachineName; /** * @brief Variable to skip a state machine pattern if the state machine name is not unique **/ bool m_SkipStateMachine; }; } // namespace mitk #endif /* STATEMACHINEFACTORY_H_HEADER_INCLUDED_C19AEDDD */ diff --git a/Core/Code/Rendering/mitkGLMapper.h b/Core/Code/Rendering/mitkGLMapper.h index 3f9fa755cd..cf35d94971 100644 --- a/Core/Code/Rendering/mitkGLMapper.h +++ b/Core/Code/Rendering/mitkGLMapper.h @@ -1,102 +1,102 @@ /*=================================================================== 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 MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 #define MITKGLMAPPER_H_HEADER_INCLUDED_C197C872 #include #include "mitkMapper.h" #include "mitkBaseRenderer.h" #include "mitkVtkPropRenderer.h" namespace mitk { /** \brief Base class of all OpenGL-based mappers. * * Those must implement the abstract method Paint(BaseRenderer), which is called by * method MitkRender(). * The Paint() method should be used to paint into a renderer via OpenGL-drawing commands. * The OpenGL context matrices (GL_MODELVIEWMATRIX/GL_PROJECTIONMATRIX) are preinitialized by * the mitkVtkPropRenderer so that the origin of the 2D-coordinate system of the 2D render * window is located in the lower left corner and has the width and height in display pixels * of the respective renderwindow. The x-axis is horizontally oriented, while the y-axis is * vertically oriented. The drawing commands are directly interpreted as display coordinates. * ApplyColorAndOpacity() can be used in the subclasses to apply color and opacity properties * read from the PropertyList. * * \ingroup Mapper */ class MITK_CORE_EXPORT GLMapper : public Mapper { public: /** \brief Do the painting into the \a renderer */ virtual void Paint(mitk::BaseRenderer *renderer) = 0; /** \brief Apply color and opacity properties read from the PropertyList * @deprecated Use ApplyColorAndOpacityProperties(...) instead */ - DEPRECATED(inline virtual void ApplyProperties(mitk::BaseRenderer* renderer) + DEPRECATED(inline virtual void ApplyProperties(mitk::BaseRenderer* renderer)) { ApplyColorAndOpacityProperties(renderer); - }); + } /** \brief Apply color and opacity properties read from the PropertyList. * The actor is not used in the GLMappers. Called by mapper subclasses. */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL); /** \brief Checks visibility and calls the paint method * * Note: The enumeration is disregarded, since OpenGL rendering only needs a * single render pass. */ void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); /** \brief Returns whether this is a vtk-based mapper * \return false, since all mappers deriving from this class are OpenGL mappers * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ DEPRECATED( virtual bool IsVtkBased() const ); /** \brief Returns whether this mapper allows picking in the renderwindow virtual bool IsPickable() const { return false; }*/ protected: /** constructor */ GLMapper(); /** virtual destructor in order to derive from this class */ virtual ~GLMapper(); private: /** copy constructor */ GLMapper( const GLMapper &); /** assignment operator */ GLMapper & operator=(const GLMapper &); }; } // namespace mitk #endif /* MITKGLMAPPER2D_H_HEADER_INCLUDED_C197C872 */ diff --git a/Core/Code/Rendering/mitkMapper.h b/Core/Code/Rendering/mitkMapper.h index 74154a7fc6..10700a442b 100644 --- a/Core/Code/Rendering/mitkMapper.h +++ b/Core/Code/Rendering/mitkMapper.h @@ -1,298 +1,298 @@ /*=================================================================== 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 MAPPER_H_HEADER_INCLUDED_C1E6EA08 #define MAPPER_H_HEADER_INCLUDED_C1E6EA08 #include #include "mitkBaseRenderer.h" #include "mitkVtkPropRenderer.h" #include "mitkLevelWindow.h" #include "mitkCommon.h" #include #include //Just included to get VTK version #include class vtkWindow; class vtkProp; namespace mitk { class BaseRenderer; class BaseData; class DataNode; /** \brief Interface for accessing (templated) LocalStorageHandler instances. */ class BaseLocalStorageHandler { public: virtual ~BaseLocalStorageHandler() {} virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true )=0; }; /** \brief Base class of all mappers, Vtk as well as OpenGL mappers * * By the help of mappers, the input data is transformed to tangible primitives, * such as surfaces, points, lines, etc. * This is the base class of all mappers, Vtk as well as OpenGL mappers. * Subclasses of mitk::Mapper control the creation of rendering primitives * that interface to the graphics library (e.g., OpenGL, vtk). * * \todo Should Mapper be a subclass of ImageSource? * \ingroup Mapper */ class MITK_CORE_EXPORT Mapper : public itk::Object { public: mitkClassMacro(Mapper, itk::Object); /** \brief Set the DataNode containing the data to map */ itkSetObjectMacro(DataNode, DataNode); /** \brief Get the DataNode containing the data to map */ virtual DataNode* GetDataNode() const; /**\brief Get the data to map * * Returns the mitk::BaseData object associated with this mapper. * \return the mitk::BaseData associated with this mapper. * @deprecated Use GetDataNode()->GetData() instead to access the data */ DEPRECATED(BaseData* GetData() const); /** \brief Convenience access method for color properties (instances of * ColorProperty) * \return \a true property was found * @deprecated Use GetDataNode()->GetColor(...) instead to get the color */ DEPRECATED(virtual bool GetColor(float rgb[3], BaseRenderer* renderer, const char* name = "color") const); /** \brief Convenience access method for visibility properties (instances * of BoolProperty) * \return \a true property was found * \sa IsVisible * @deprecated Use GetDataNode()->GetVisibility(...) instead to get the visibility */ DEPRECATED(virtual bool GetVisibility(bool &visible, BaseRenderer* renderer, const char* name = "visible") const); /** \brief Convenience access method for opacity properties (instances of * FloatProperty) * \return \a true property was found * @deprecated Use GetDataNode()->GetOpacity(...) instead to get the opacity */ DEPRECATED(virtual bool GetOpacity(float &opacity, BaseRenderer* renderer, const char* name = "opacity") const); /** \brief Convenience access method for color properties (instances of * LevelWindoProperty) * \return \a true property was found * @deprecated Use GetDataNode->GetLevelWindow(...) instead to get the levelwindow */ DEPRECATED(virtual bool GetLevelWindow(LevelWindow &levelWindow, BaseRenderer* renderer, const char* name = "levelwindow") const); /** \brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (\a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * \sa GetVisibility * @deprecated Use GetDataNode()->GetVisibility(...) instead */ DEPRECATED(virtual bool IsVisible(BaseRenderer* renderer, const char* name = "visible") const); /** \brief Returns whether this is an vtk-based mapper * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ virtual bool IsVtkBased() const = 0; /** \brief Calls the time step of the input data for the specified renderer and checks * whether the time step is valid and calls method GenerateDataForRenderer() */ virtual void Update(BaseRenderer* renderer); /** \brief Responsible for calling the appropriate render functions. * To be implemented in sub-classes. */ virtual void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type) = 0; /** * \brief Apply specific color and opacity properties read from the PropertyList. * Reimplemented in GLmapper (does not use the actor) and the VtkMapper class. * The function is called by the individual mapper (mostly in the ApplyProperties() or ApplyAllProperties() * method). */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor* actor = NULL) = 0; /** \brief Set default values of properties used by this mapper * to \a node * * \param node The node for which the properties are set * \param overwrite overwrite existing properties (default: \a false) * \param renderer defines which property list of node is used * (default: \a NULL, i.e. default property list) */ static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false); /** \brief Returns the current time step as calculated from the renderer */ int GetTimestep() const { return m_TimeStep; }; /** Returns true if this Mapper currently allows for Level-of-Detail rendering. * This reflects whether this Mapper currently invokes StartEvent, EndEvent, and * ProgressEvent on BaseRenderer. */ virtual bool IsLODEnabled( BaseRenderer * /*renderer*/ ) const { return false; } protected: /** \brief explicit constructor which disallows implicit conversions */ explicit Mapper(); /** \brief virtual destructor in order to derive from this class */ virtual ~Mapper(); /** \brief Generate the data needed for rendering (independent of a specific renderer) */ // @deprecated Use GenerateDataForRenderer(BaseRenderer* renderer) instead. - DEPRECATED( virtual void GenerateData() { }); + DEPRECATED( virtual void GenerateData()) { } /** \brief Generate the data needed for rendering into \a renderer */ - virtual void GenerateDataForRenderer(BaseRenderer* /* renderer */) { }; + virtual void GenerateDataForRenderer(BaseRenderer* /* renderer */) { } /** \brief Updates the time step, which is sometimes needed in subclasses */ virtual void CalculateTimeStep( BaseRenderer* renderer ); /** \brief Reset the mapper (i.e., make sure that nothing is displayed) if no * valid data is present. In most cases the reimplemented function * disables the according actors (toggling visibility off) * * To be implemented in sub-classes. */ virtual void ResetMapper( BaseRenderer* /*renderer*/ ) { }; //\brief not thread-safe itk::WeakPointer m_DataNode; /** \brief timestamp of last update of stored data */ itk::TimeStamp m_LastUpdateTime; private: /** \brief The current time step of the dataset to be rendered, * for use in subclasses. * The current timestep can be accessed via the GetTimestep() method. */ int m_TimeStep; /** \brief copy constructor */ Mapper( const Mapper &); /** \brief assignment operator */ Mapper &operator=(const Mapper &); public: /** \brief Base class for mapper specific rendering ressources. */ class BaseLocalStorage { }; /** \brief Templated class for management of LocalStorage implementations in Mappers. * * The LocalStorageHandler is responsible for providing a LocalStorage to a * concrete mitk::Mapper subclass. Each RenderWindow / mitk::BaseRenderer is * assigned its own LocalStorage instance so that all contained ressources * (actors, shaders, textures, ...) are provided individually per window. * */ template class LocalStorageHandler : public mitk::BaseLocalStorageHandler { protected: std::map m_BaseRenderer2LS; public: /** \brief deallocates a local storage for a specifc BaseRenderer (if the * BaseRenderer is itself deallocating it in its destructor, it has to set * unregisterFromBaseRenderer=false) */ virtual void ClearLocalStorage(mitk::BaseRenderer *renderer,bool unregisterFromBaseRenderer=true ) { //MITK_INFO << "deleting a localstorage on a mapper request"; if(unregisterFromBaseRenderer) renderer->UnregisterLocalStorageHandler( this ); L *l = m_BaseRenderer2LS[renderer]; m_BaseRenderer2LS.erase( renderer ); delete l; } /** \brief Retrieves a LocalStorage for a specific BaseRenderer. * * Should be used by mappers in GenerateDataForRenderer() */ L *GetLocalStorage(mitk::BaseRenderer *forRenderer) { L *l = m_BaseRenderer2LS[ forRenderer ]; if(!l) { //MITK_INFO << "creating new localstorage"; l = new L; m_BaseRenderer2LS[ forRenderer ] = l; forRenderer->RegisterLocalStorageHandler( this ); } return l; } ~LocalStorageHandler() { typename std::map::iterator it; for ( it=m_BaseRenderer2LS.begin() ; it != m_BaseRenderer2LS.end(); it++ ) { (*it).first->UnregisterLocalStorageHandler(this); delete (*it).second; } m_BaseRenderer2LS.clear(); } }; }; } // namespace mitk #endif /* MAPPER_H_HEADER_INCLUDED_C1E6EA08 */ diff --git a/Core/Code/Rendering/mitkRenderingTestHelper.cpp b/Core/Code/Rendering/mitkRenderingTestHelper.cpp index 7f319a0130..cf646c1de3 100644 --- a/Core/Code/Rendering/mitkRenderingTestHelper.cpp +++ b/Core/Code/Rendering/mitkRenderingTestHelper.cpp @@ -1,191 +1,191 @@ /*=================================================================== 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. ===================================================================*/ //VTK #include #include #include #include //MITK #include #include #include #include #include #include #include // include gl to read out properties #include #include mitkRenderingTestHelper::mitkRenderingTestHelper(int width, int height, int argc, char* argv[]) { // Global interaction must(!) be initialized mitk::GlobalInteraction::GetInstance()->Initialize("global"); m_DataStorage = mitk::StandaloneDataStorage::New(); m_RenderWindow = mitk::RenderWindow::New(); m_RenderWindow->GetRenderer()->SetDataStorage(m_DataStorage); m_RenderWindow->GetRenderer()->SetMapperID(mitk::BaseRenderer::Standard2D); this->GetVtkRenderWindow()->SetSize( width, height ); m_RenderWindow->GetRenderer()->Resize( width, height); //this->GetVtkRenderWindow()->DoubleBufferOff( ); this->SetInputFileNames(argc, argv); // prints the glinfo after creation of the vtkrenderwindow this->PrintGLInfo(); } mitkRenderingTestHelper::~mitkRenderingTestHelper() { } void mitkRenderingTestHelper::PrintGLInfo() { GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);; MITK_INFO << "OpenGL Render Context Information: \n" << "- GL_VENDOR: "<< glGetString(GL_VENDOR) << "\n" << "- GL_RENDERER: "<< glGetString(GL_RENDERER) << "\n" << "- GL_VERSION: "<< glGetString(GL_VERSION) << "\n" << "- GL_MAX_TEXTURE_SIZE: "<< maxTextureSize << "\n" << "- GL_EXTENSIONS: "<< glGetString(GL_EXTENSIONS); } void mitkRenderingTestHelper::SetMapperID( mitk::BaseRenderer::StandardMapperSlot id) { m_RenderWindow->GetRenderer()->SetMapperID(id); } void mitkRenderingTestHelper::Render() { //if the datastorage is initialized and at least 1 image is loaded render it if(m_DataStorage.IsNotNull() || m_DataStorage->GetAll()->Size() >= 1 ) { //perform global reinit: m_RenderWindow->GetRenderer()->PrepareRender(); // mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->GetVtkRenderWindow()); //use this to actually show the iamge in a renderwindow this->GetVtkRenderWindow()->Render(); // this->GetVtkRenderWindow()->GetInteractor()->Start(); } else { MITK_ERROR << "No images loaded in data storage!"; } } void mitkRenderingTestHelper::PrepareRender() { //perform global reinit: m_RenderWindow->GetRenderer()->PrepareRender(); } mitk::DataStorage::Pointer mitkRenderingTestHelper::GetDataStorage() { return m_DataStorage; } void mitkRenderingTestHelper::SetInputFileNames(int argc, char* argv[]) { // parse parameters for (int i = 1; i < argc; ++i) { //add everything to a list but -T and -V std::string tmp = argv[i]; if((tmp.compare("-T")) && (tmp.compare("-V"))) { this->AddToStorage(tmp); } else { break; } } } void mitkRenderingTestHelper::SetViewDirection(mitk::SliceNavigationController::ViewDirection viewDirection) { mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController()->SetDefaultViewDirection(viewDirection); mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()) ); } void mitkRenderingTestHelper::ReorientSlices(mitk::Point3D origin, mitk::Vector3D rotation) { mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::BaseRenderer::GetInstance(m_RenderWindow->GetVtkRenderWindow())->GetSliceNavigationController(); sliceNavigationController->ReorientSlices(origin, rotation); } vtkRenderer* mitkRenderingTestHelper::GetVtkRenderer() { return m_RenderWindow->GetRenderer()->GetVtkRenderer(); } void mitkRenderingTestHelper::SetImageProperty(const char *propertyKey, mitk::BaseProperty* property ) { this->m_DataStorage->GetNode(mitk::NodePredicateDataType::New("Image"))->SetProperty(propertyKey, property); } vtkRenderWindow* mitkRenderingTestHelper::GetVtkRenderWindow() { return m_RenderWindow->GetVtkRenderWindow(); } //method to save a screenshot of the renderwindow (e.g. create a reference screenshot) void mitkRenderingTestHelper::SaveAsPNG(std::string fileName) { vtkSmartPointer renderer = this->GetVtkRenderer(); bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() ); renderer->GetRenderWindow()->DoubleBufferOff(); vtkSmartPointer magnifier = vtkSmartPointer::New(); magnifier->SetInput(renderer); - magnifier->SetMagnification(1.0); + magnifier->SetMagnification(1); vtkSmartPointer fileWriter = vtkSmartPointer::New(); fileWriter->SetInput(magnifier->GetOutput()); fileWriter->SetFileName(fileName.c_str()); fileWriter->Write(); renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering); } void mitkRenderingTestHelper::AddToStorage(const std::string &filename) { try { mitk::DataNode::Pointer node = mitk::IOUtil::LoadDataNode(filename); this->AddNodeToStorage(node); } catch ( itk::ExceptionObject & e ) { MITK_ERROR << "Failed loading test data '" << filename << "': " << e.what(); } } void mitkRenderingTestHelper::AddNodeToStorage(mitk::DataNode::Pointer node) { this->m_DataStorage->Add(node); mitk::RenderingManager::GetInstance()->InitializeViews( m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()) ); } diff --git a/Core/Code/Rendering/mitkVtkMapper.h b/Core/Code/Rendering/mitkVtkMapper.h index 789b1f52ad..cb544e5473 100644 --- a/Core/Code/Rendering/mitkVtkMapper.h +++ b/Core/Code/Rendering/mitkVtkMapper.h @@ -1,145 +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. ===================================================================*/ // change number #ifndef VTKMAPPER_H_HEADER_INCLUDED_C1C5453B #define VTKMAPPER_H_HEADER_INCLUDED_C1C5453B #include #include "mitkMapper.h" #include "mitkBaseRenderer.h" #include "mitkDataNode.h" #include "mitkVtkPropRenderer.h" #include #include #include #include #include #include #include #include class vtkProp; class vtkProp3D; class vtkActor; namespace mitk { /** \brief Base class of all Vtk Mappers in order to display primitives * by exploiting Vtk functionality. * * Rendering of opaque, translucent or volumetric geometry and overlays * is done in consecutive render passes. * * \ingroup Mapper */ class MITK_CORE_EXPORT VtkMapper : public Mapper { public: mitkClassMacro(VtkMapper,Mapper); virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer) = 0; /** \brief Re-issues all drawing commands required to describe * the entire scene each time a new frame is required, * regardless of actual changes. */ static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); /** * \brief Returns whether this is an vtk-based mapper * @deprecated All mappers of superclass VTKMapper are vtk based, use a dynamic_cast instead */ DEPRECATED( virtual bool IsVtkBased() const ); /** \brief Determines which geometry should be rendered * (opaque, translucent, volumetric, overlay) * and calls the appropriate function. * * Called by mitk::VtkPropRenderer::Render */ void MitkRender(mitk::BaseRenderer* renderer, mitk::VtkPropRenderer::RenderType type); /** \brief Checks visibility and renders the overlay */ virtual void MitkRenderOverlay(BaseRenderer* renderer); /** \brief Checks visibility and renders untransparent geometry */ virtual void MitkRenderOpaqueGeometry(BaseRenderer* renderer); /** \brief Checks visiblity and renders transparent geometry */ virtual void MitkRenderTranslucentGeometry(BaseRenderer* renderer); /** \brief Checks visibility and renders volumes */ virtual void MitkRenderVolumetricGeometry(BaseRenderer* renderer); /** \brief Returns true if this mapper owns the specified vtkProp for * the given BaseRenderer. * * Note: returns false by default; should be implemented for VTK-based * Mapper subclasses. */ virtual bool HasVtkProp( const vtkProp *prop, BaseRenderer *renderer ); /** \brief Set the vtkTransform of the m_Prop3D for * the current time step of \a renderer * * Called by mitk::VtkPropRenderer::Update before rendering */ virtual void UpdateVtkTransform(mitk::BaseRenderer *renderer); /** * \brief Apply color and opacity properties read from the PropertyList * @deprecated Use ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor) instead */ - DEPRECATED(inline virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer) + DEPRECATED(inline virtual void ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer)) { ApplyColorAndOpacityProperties(renderer, actor); - }); + } /** * \brief Apply color and opacity properties read from the PropertyList. * Called by mapper subclasses. */ virtual void ApplyColorAndOpacityProperties(mitk::BaseRenderer* renderer, vtkActor * actor); /** * \brief Release vtk-based graphics resources that are being consumed by this mapper. * The parameter window could be used to determine which graphic * resources to releases. Must be overwritten in individual subclasses * if vtkProps are used. */ virtual void ReleaseGraphicsResources(vtkWindow* /*renWin*/) { }; protected: /** constructor */ VtkMapper(); /** virtual destructor in order to derive from this class */ virtual ~VtkMapper(); private: /** copy constructor */ VtkMapper( const VtkMapper &); /** assignment operator */ VtkMapper & operator=(const VtkMapper &); }; } // namespace mitk #endif /* VTKMAPPER_H_HEADER_INCLUDED_C1C5453B */ diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.cpp b/Core/Code/Rendering/mitkVtkPropRenderer.cpp index af3f9d444e..59fc8efcef 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.cpp +++ b/Core/Code/Rendering/mitkVtkPropRenderer.cpp @@ -1,927 +1,926 @@ /*=================================================================== 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 "mitkVtkPropRenderer.h" // MAPPERS #include "mitkMapper.h" #include "mitkImageVtkMapper2D.h" #include "mitkVtkMapper.h" #include "mitkGLMapper.h" #include "mitkGeometry2DDataVtkMapper3D.h" #include "mitkPointSetGLMapper2D.h" #include "mitkImageSliceSelector.h" #include "mitkRenderingManager.h" #include "mitkGL.h" #include "mitkGeometry3D.h" #include "mitkDisplayGeometry.h" #include "mitkLevelWindow.h" #include "mitkCameraController.h" #include "mitkVtkInteractorCameraController.h" #include "mitkPlaneGeometry.h" #include "mitkProperties.h" #include "mitkSurface.h" #include "mitkNodePredicateDataType.h" #include "mitkVtkInteractorStyle.h" // VTK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include mitk::VtkPropRenderer::VtkPropRenderer( const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm ) : BaseRenderer(name,renWin, rm), m_VtkMapperPresent(false), - m_NewRenderer(true), m_CameraInitializedForMapperID(0) { didCount=false; m_WorldPointPicker = vtkWorldPointPicker::New(); m_PointPicker = vtkPointPicker::New(); m_PointPicker->SetTolerance( 0.0025 ); m_CellPicker = vtkCellPicker::New(); m_CellPicker->SetTolerance( 0.0025 ); mitk::Geometry2DDataVtkMapper3D::Pointer geometryMapper = mitk::Geometry2DDataVtkMapper3D::New(); m_CurrentWorldGeometry2DMapper = geometryMapper; m_CurrentWorldGeometry2DNode->SetMapper(2, geometryMapper); m_LightKit = vtkLightKit::New(); m_LightKit->AddLightsToRenderer(m_VtkRenderer); m_PickingMode = WorldPointPicking; m_TextRenderer = vtkRenderer::New(); m_TextRenderer->SetRenderWindow(renWin); m_TextRenderer->SetInteractive(0); m_TextRenderer->SetErase(0); } /*! \brief Destructs the VtkPropRenderer. */ mitk::VtkPropRenderer::~VtkPropRenderer() { // Workaround for GLDisplayList Bug { m_MapperID=0; checkState(); } if (m_LightKit != NULL) m_LightKit->Delete(); if (m_VtkRenderer!=NULL) { m_CameraController = NULL; m_VtkRenderer->Delete(); m_VtkRenderer = NULL; } else m_CameraController = NULL; if (m_WorldPointPicker != NULL) m_WorldPointPicker->Delete(); if (m_PointPicker != NULL) m_PointPicker->Delete(); if (m_CellPicker != NULL) m_CellPicker->Delete(); if (m_TextRenderer != NULL) m_TextRenderer->Delete(); } void mitk::VtkPropRenderer::SetDataStorage( mitk::DataStorage* storage ) { if ( storage == NULL ) return; BaseRenderer::SetDataStorage(storage); static_cast(m_CurrentWorldGeometry2DMapper.GetPointer())->SetDataStorageForTexture( m_DataStorage.GetPointer() ); // Compute the geometry from the current data tree bounds and set it as world geometry this->SetWorldGeometryToDataStorageBounds(); } bool mitk::VtkPropRenderer::SetWorldGeometryToDataStorageBounds() { if ( m_DataStorage.IsNull() ) return false; //initialize world geometry mitk::TimeSlicedGeometry::Pointer geometry = m_DataStorage->ComputeVisibleBoundingGeometry3D( NULL, "includeInBoundingBox" ); if ( geometry.IsNull() ) return false; this->SetWorldGeometry(geometry); //this->GetDisplayGeometry()->SetSizeInDisplayUnits( this->m_TextRenderer->GetRenderWindow()->GetSize()[0], this->m_TextRenderer->GetRenderWindow()->GetSize()[1] ); this->GetDisplayGeometry()->Fit(); this->GetVtkRenderer()->ResetCamera(); this->Modified(); return true; } /*! \brief Called by the vtkMitkRenderProp in order to start MITK rendering process. */ int mitk::VtkPropRenderer::Render(mitk::VtkPropRenderer::RenderType type) { // Do we have objects to render? if ( this->GetEmptyWorldGeometry()) return 0; if ( m_DataStorage.IsNull()) return 0; // Update mappers and prepare mapper queue if (type == VtkPropRenderer::Opaque) this->PrepareMapperQueue(); //go through the generated list and let the sorted mappers paint bool lastVtkBased = true; //bool sthVtkBased = false; for(MappersMapType::iterator it = m_MappersMap.begin(); it != m_MappersMap.end(); it++) { Mapper * mapper = (*it).second; VtkMapper* vtkmapper = dynamic_cast(mapper); if(vtkmapper) { //sthVtkBased = true; if(!lastVtkBased) { Disable2DOpenGL(); lastVtkBased = true; } } else if(lastVtkBased) { Enable2DOpenGL(); lastVtkBased = false; } mapper->MitkRender(this, type); } if (lastVtkBased == false) Disable2DOpenGL(); // Render text if (type == VtkPropRenderer::Overlay) { if (m_TextCollection.size() > 0) { for (TextMapType::iterator it = m_TextCollection.begin(); it != m_TextCollection.end() ; it++) m_TextRenderer->AddViewProp((*it).second); m_TextRenderer->Render(); } } return 1; } /*! \brief PrepareMapperQueue iterates the datatree PrepareMapperQueue iterates the datatree in order to find mappers which shall be rendered. Also, it sortes the mappers wrt to their layer. */ void mitk::VtkPropRenderer::PrepareMapperQueue() { // variable for counting LOD-enabled mappers m_NumberOfVisibleLODEnabledMappers = 0; // Do we have to update the mappers ? if ( m_LastUpdateTime < GetMTime() || m_LastUpdateTime < GetDisplayGeometry()->GetMTime() ) { Update(); } else if (m_MapperID>=1 && m_MapperID < 6) Update(); // remove all text properties before mappers will add new ones m_TextRenderer->RemoveAllViewProps(); for ( unsigned int i=0; iDelete(); } m_TextCollection.clear(); // clear priority_queue m_MappersMap.clear(); int mapperNo = 0; //DataStorage if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper::Pointer mapper = node->GetMapper(m_MapperID); if ( mapper.IsNull() ) continue; bool visible = true; node->GetVisibility(visible, this, "visible"); // The information about LOD-enabled mappers is required by RenderingManager if ( mapper->IsLODEnabled( this ) && visible ) { ++m_NumberOfVisibleLODEnabledMappers; } // mapper without a layer property get layer number 1 int layer = 1; node->GetIntProperty("layer", layer, this); int nr = (layer<<16) + mapperNo; m_MappersMap.insert( std::pair< int, Mapper * >( nr, mapper ) ); mapperNo++; } } /*! \brief Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Enable2DOpenGL() { GLint iViewport[4]; // Get a copy of the viewport glGetIntegerv( GL_VIEWPORT, iViewport ); // Save a copy of the projection matrix so that we can restore it // when it's time to do 3D rendering again. glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); // Set up the orthographic projection glOrtho( iViewport[0], iViewport[0]+iViewport[2], iViewport[1], iViewport[1]+iViewport[3], -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); // Make sure depth testing and lighting are disabled for 2D rendering until // we are finished rendering in 2D glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); // disable the texturing here so crosshair is painted in the correct colors // vtk will reenable texturing every time it is needed glDisable( GL_TEXTURE_1D ); glDisable( GL_TEXTURE_2D ); } /*! \brief Initialize the VtkPropRenderer Enable2DOpenGL() and Disable2DOpenGL() are used to switch between 2D rendering (orthographic projection) and 3D rendering (perspective projection) */ void mitk::VtkPropRenderer::Disable2DOpenGL() { glPopAttrib(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } void mitk::VtkPropRenderer::Update(mitk::DataNode* datatreenode) { if(datatreenode!=NULL) { mitk::Mapper::Pointer mapper = datatreenode->GetMapper(m_MapperID); if(mapper.IsNotNull()) { GLMapper* glmapper=dynamic_cast(mapper.GetPointer()); if(GetDisplayGeometry()->IsValid()) { if(glmapper != NULL) { glmapper->Update(this); m_VtkMapperPresent=false; } else { VtkMapper* vtkmapper=dynamic_cast(mapper.GetPointer()); if(vtkmapper != NULL) { vtkmapper->Update(this); vtkmapper->UpdateVtkTransform(this); m_VtkMapperPresent=true; } } } } } } void mitk::VtkPropRenderer::Update() { if( m_DataStorage.IsNull() ) return; m_VtkMapperPresent = false; mitk::DataStorage::SetOfObjects::ConstPointer all = m_DataStorage->GetAll(); for (mitk::DataStorage::SetOfObjects::ConstIterator it = all->Begin(); it != all->End(); ++it) Update(it->Value()); Modified(); m_LastUpdateTime = GetMTime(); } /*! \brief This method is called from the two Constructors */ void mitk::VtkPropRenderer::InitRenderer(vtkRenderWindow* renderWindow) { BaseRenderer::InitRenderer(renderWindow); if(renderWindow == NULL) { m_InitNeeded = false; m_ResizeNeeded = false; return; } m_InitNeeded = true; m_ResizeNeeded = true; m_LastUpdateTime = 0; } /*! \brief Resize the OpenGL Window */ void mitk::VtkPropRenderer::Resize(int w, int h) { BaseRenderer::Resize(w, h); m_RenderingManager->RequestUpdate(this->GetRenderWindow()); } void mitk::VtkPropRenderer::InitSize(int w, int h) { m_RenderWindow->SetSize(w,h); Superclass::InitSize(w, h); Modified(); Update(); if(m_VtkRenderer!=NULL) { int w=vtkObject::GetGlobalWarningDisplay(); vtkObject::GlobalWarningDisplayOff(); m_VtkRenderer->ResetCamera(); vtkObject::SetGlobalWarningDisplay(w); } } void mitk::VtkPropRenderer::SetMapperID(const MapperSlotId mapperId) { if(m_MapperID != mapperId) Superclass::SetMapperID(mapperId); // Workaround for GL Displaylist Bug checkState(); } /*! \brief Activates the current renderwindow. */ void mitk::VtkPropRenderer::MakeCurrent() { if(m_RenderWindow!=NULL) m_RenderWindow->MakeCurrent(); } void mitk::VtkPropRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const { if(m_VtkMapperPresent) { //m_WorldPointPicker->SetTolerance (0.0001); switch ( m_PickingMode ) { case (WorldPointPicking) : { m_WorldPointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_WorldPointPicker->GetPickPosition(), worldPoint); break; } case (PointPicking) : { // create a new vtkRenderer // give it all necessary information (camera position, etc.) // get all surfaces from datastorage, get actors from them // add all those actors to the new renderer // give this new renderer to pointpicker /* vtkRenderer* pickingRenderer = vtkRenderer::New(); pickingRenderer->SetActiveCamera( ); DataStorage* dataStorage = m_DataStorage; TNodePredicateDataType isSurface; DataStorage::SetOfObjects::ConstPointer allSurfaces = dataStorage->GetSubset( isSurface ); MITK_INFO << "in picking: got " << allSurfaces->size() << " surfaces." << std::endl; for (DataStorage::SetOfObjects::const_iterator iter = allSurfaces->begin(); iter != allSurfaces->end(); ++iter) { const DataNode* currentNode = *iter; VtkMapper3D* baseVtkMapper3D = dynamic_cast( currentNode->GetMapper( BaseRenderer::Standard3D ) ); if ( baseVtkMapper3D ) { vtkActor* actor = dynamic_cast( baseVtkMapper3D->GetViewProp() ); if (actor) { MITK_INFO << "a" << std::flush; pickingRenderer->AddActor( actor ); } } } MITK_INFO << ";" << std::endl; */ m_PointPicker->Pick(displayPoint[0], displayPoint[1], 0, m_VtkRenderer); vtk2itk(m_PointPicker->GetPickPosition(), worldPoint); break; } } } else { Superclass::PickWorldPoint(displayPoint, worldPoint); } } mitk::DataNode * mitk::VtkPropRenderer::PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const { if ( m_VtkMapperPresent ) { m_CellPicker->InitializePickList(); // Iterate over all DataStorage objects to determine all vtkProps intended // for picking DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it ) { DataNode *node = it->Value(); if ( node == NULL ) continue; bool pickable = false; node->GetBoolProperty( "pickable", pickable ); if ( !pickable ) continue; VtkMapper *mapper = dynamic_cast < VtkMapper * > ( node->GetMapper( m_MapperID ) ); if ( mapper == NULL ) continue; vtkProp *prop = mapper->GetVtkProp( (mitk::BaseRenderer *)this ); if ( prop == NULL ) continue; m_CellPicker->AddPickList( prop ); } // Do the picking and retrieve the picked vtkProp (if any) m_CellPicker->PickFromListOn(); m_CellPicker->Pick( displayPosition[0], displayPosition[1], 0.0, m_VtkRenderer ); m_CellPicker->PickFromListOff(); vtk2itk( m_CellPicker->GetPickPosition(), worldPosition ); vtkProp *prop = m_CellPicker->GetViewProp(); if ( prop == NULL ) { return NULL; } // Iterate over all DataStorage objects to determine if the retrieved // vtkProp is owned by any associated mapper. for ( DataStorage::SetOfObjects::ConstIterator it = allObjects->Begin(); it != allObjects->End(); ++it) { DataNode::Pointer node = it->Value(); if ( node.IsNull() ) continue; mitk::Mapper * mapper = node->GetMapper( m_MapperID ); if ( mapper == NULL) continue; mitk::VtkMapper * vtkmapper = dynamic_cast< VtkMapper * >(mapper); if(vtkmapper){ //if vtk-based, then ... if ( vtkmapper->HasVtkProp( prop, const_cast< mitk::VtkPropRenderer * >( this ) ) ) { return node; } } } return NULL; } else { return Superclass::PickObject( displayPosition, worldPosition ); } }; /*! \brief Writes some 2D text as overlay. Function returns an unique int Text_ID for each call, which can be used via the GetTextLabelProperty(int text_id) function in order to get a vtkTextProperty. This property enables the setup of font, font size, etc. */ int mitk::VtkPropRenderer::WriteSimpleText(std::string text, double posX, double posY, double color1, double color2, double color3, float opacity) { if(text.size() > 0) { vtkTextActor* textActor = vtkTextActor::New(); textActor->SetPosition(posX,posY); textActor->SetInput(text.c_str()); textActor->GetTextProperty()->SetColor(color1, color2, color3); //TODO: Read color from node property textActor->GetTextProperty()->SetOpacity( opacity ); int text_id = m_TextCollection.size(); m_TextCollection.insert(TextMapType::value_type(text_id,textActor)); return text_id; } return -1; } /*! \brief Can be used in order to get a vtkTextProperty for a specific text_id. This property enables the setup of font, font size, etc. */ vtkTextProperty* mitk::VtkPropRenderer::GetTextLabelProperty(int text_id) { return this->m_TextCollection[text_id]->GetTextProperty(); } void mitk::VtkPropRenderer::InitPathTraversal() { if (m_DataStorage.IsNotNull()) { m_PickingObjects = m_DataStorage->GetAll(); m_PickingObjectsIterator = m_PickingObjects->begin(); } } vtkAssemblyPath* mitk::VtkPropRenderer::GetNextPath() { if (m_DataStorage.IsNull() ) { return NULL; } if ( m_PickingObjectsIterator == m_PickingObjects->end() ) { return NULL; } vtkAssemblyPath* returnPath = vtkAssemblyPath::New(); //returnPath->Register(NULL); bool success = false; while (!success) { // loop until AddNode can be called successfully const DataNode* node = *m_PickingObjectsIterator; if (node) { Mapper* mapper = node->GetMapper( BaseRenderer::Standard3D ); if (mapper) { VtkMapper* vtkmapper = dynamic_cast( mapper ); if (vtkmapper) { vtkProp* prop = vtkmapper->GetVtkProp(this); if ( prop && prop->GetVisibility() ) { // add to assembly path returnPath->AddNode( prop, prop->GetMatrix() ); success = true; } } } } ++m_PickingObjectsIterator; if ( m_PickingObjectsIterator == m_PickingObjects->end() ) break; } if ( success ) { return returnPath; } else { return NULL; } } void mitk::VtkPropRenderer::ReleaseGraphicsResources(vtkWindow *renWin) { if( m_DataStorage.IsNull() ) return; DataStorage::SetOfObjects::ConstPointer allObjects = m_DataStorage->GetAll(); for (DataStorage::SetOfObjects::const_iterator iter = allObjects->begin(); iter != allObjects->end(); ++iter) { DataNode::Pointer node = *iter; if ( node.IsNull() ) continue; Mapper * mapper = node->GetMapper(m_MapperID); if (mapper) { VtkMapper* vtkmapper = dynamic_cast( mapper ); if(vtkmapper) vtkmapper->ReleaseGraphicsResources(renWin); } } } const vtkWorldPointPicker *mitk::VtkPropRenderer::GetWorldPointPicker() const { return m_WorldPointPicker; } const vtkPointPicker *mitk::VtkPropRenderer::GetPointPicker() const { return m_PointPicker; } const vtkCellPicker *mitk::VtkPropRenderer::GetCellPicker() const { return m_CellPicker; } mitk::VtkPropRenderer::MappersMapType mitk::VtkPropRenderer::GetMappersMap() const { return m_MappersMap; } // Workaround for GL Displaylist bug static int glWorkAroundGlobalCount = 0; bool mitk::VtkPropRenderer::useImmediateModeRendering() { return glWorkAroundGlobalCount>1; } void mitk::VtkPropRenderer::checkState() { if (m_MapperID == Standard3D) { if (!didCount) { didCount = true; glWorkAroundGlobalCount++; if (glWorkAroundGlobalCount == 2) { MITK_INFO << "Multiple 3D Renderwindows active...: turning Immediate Rendering ON for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOn(); } //MITK_INFO << "GLOBAL 3D INCREASE " << glWorkAroundGlobalCount << "\n"; } } else { if(didCount) { didCount=false; glWorkAroundGlobalCount--; if(glWorkAroundGlobalCount==1) { MITK_INFO << "Single 3D Renderwindow active...: turning Immediate Rendering OFF for legacy mappers"; // vtkMapper::GlobalImmediateModeRenderingOff(); } //MITK_INFO << "GLOBAL 3D DECREASE " << glWorkAroundGlobalCount << "\n"; } } } //### Contains all methods which are neceassry before each VTK Render() call void mitk::VtkPropRenderer::PrepareRender() { if ( this->GetMapperID() != m_CameraInitializedForMapperID ) { Initialize2DvtkCamera(); //Set parallel projection etc. } AdjustCameraToScene(); //Prepare camera for 2D render windows } bool mitk::VtkPropRenderer::Initialize2DvtkCamera() { if ( this->GetMapperID() == Standard3D ) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(false); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( vtkInteractorStyleTrackballCamera::New() ); m_CameraInitializedForMapperID = Standard3D; } else if( this->GetMapperID() == Standard2D) { //activate parallel projection for 2D this->GetVtkRenderer()->GetActiveCamera()->SetParallelProjection(true); //turn the light out in the scene in order to render correct grey values. //TODO Implement a property for light in the 2D render windows (in another method) this->GetVtkRenderer()->RemoveAllLights(); this->GetRenderWindow()->GetInteractor()->SetInteractorStyle( mitkVtkInteractorStyle::New() ); m_CameraInitializedForMapperID = Standard2D; } return true; } void mitk::VtkPropRenderer::AdjustCameraToScene(){ if(this->GetMapperID() == Standard2D) { const mitk::DisplayGeometry* displayGeometry = this->GetDisplayGeometry(); double objectHeightInMM = this->GetCurrentWorldGeometry2D()->GetExtentInMM(1);//the height of the current object slice in mm double displayHeightInMM = displayGeometry->GetSizeInMM()[1]; //the display height in mm (gets smaller when you zoom in) double zoomFactor = objectHeightInMM/displayHeightInMM; //displayGeometry->GetScaleFactorMMPerDisplayUnit() //determine how much of the object can be displayed Vector2D displayGeometryOriginInMM = displayGeometry->GetOriginInMM(); //top left of the render window (Origin) Vector2D displayGeometryCenterInMM = displayGeometryOriginInMM + displayGeometry->GetSizeInMM()*0.5; //center of the render window: (Origin + Size/2) //Scale the rendered object: //The image is scaled by a single factor, because in an orthographic projection sizes //are preserved (so you cannot scale X and Y axis with different parameters). The //parameter sets the size of the total display-volume. If you set this to the image //height, the image plus a border with the size of the image will be rendered. //Therefore, the size is imageHeightInMM / 2. this->GetVtkRenderer()->GetActiveCamera()->SetParallelScale(objectHeightInMM*0.5 ); //zooming with the factor calculated by dividing displayHeight through imegeHeight. The factor is inverse, because the VTK zoom method is working inversely. this->GetVtkRenderer()->GetActiveCamera()->Zoom(zoomFactor); //the center of the view-plane double viewPlaneCenter[3]; viewPlaneCenter[0] = displayGeometryCenterInMM[0]; viewPlaneCenter[1] = displayGeometryCenterInMM[1]; viewPlaneCenter[2] = 0.0; //the view-plane is located in the XY-plane with Z=0.0 //define which direction is "up" for the ciamera (like default for vtk (0.0, 1.0, 0.0) double cameraUp[3]; cameraUp[0] = 0.0; cameraUp[1] = 1.0; cameraUp[2] = 0.0; //the position of the camera (center[0], center[1], 900000) double cameraPosition[3]; cameraPosition[0] = viewPlaneCenter[0]; cameraPosition[1] = viewPlaneCenter[1]; cameraPosition[2] = 900000.0; //Reason for 900000: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. //set the camera corresponding to the textured plane vtkSmartPointer camera = this->GetVtkRenderer()->GetActiveCamera(); if (camera) { camera->SetPosition( cameraPosition ); //set the camera position on the textured plane normal (in our case this is the view plane normal) camera->SetFocalPoint( viewPlaneCenter ); //set the focal point to the center of the textured plane camera->SetViewUp( cameraUp ); //set the view-up for the camera // double distance = sqrt((cameraPosition[2]-viewPlaneCenter[2])*(cameraPosition[2]-viewPlaneCenter[2])); // camera->SetClippingRange(distance-50, distance+50); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. camera->SetClippingRange(0.1, 1000000); //Reason for huge range: VTK seems to calculate the clipping planes wrong for small values. See VTK bug (id #7823) in VTK bugtracker. } const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( this->GetCurrentWorldGeometry2D() ); if ( planeGeometry != NULL ) { //Transform the camera to the current position (transveral, coronal and saggital plane). //This is necessary, because the SetUserTransform() method does not manipulate the vtkCamera. //(Without not all three planes would be visible). vtkSmartPointer trans = vtkSmartPointer::New(); vtkSmartPointer matrix = vtkSmartPointer::New(); Point3D origin; Vector3D right, bottom, normal; origin = planeGeometry->GetOrigin(); right = planeGeometry->GetAxisVector( 0 ); // right = Extent of Image in mm (worldspace) bottom = planeGeometry->GetAxisVector( 1 ); normal = planeGeometry->GetNormal(); right.Normalize(); bottom.Normalize(); normal.Normalize(); matrix->SetElement(0, 0, right[0]); matrix->SetElement(1, 0, right[1]); matrix->SetElement(2, 0, right[2]); matrix->SetElement(0, 1, bottom[0]); matrix->SetElement(1, 1, bottom[1]); matrix->SetElement(2, 1, bottom[2]); matrix->SetElement(0, 2, normal[0]); matrix->SetElement(1, 2, normal[1]); matrix->SetElement(2, 2, normal[2]); matrix->SetElement(0, 3, origin[0]); matrix->SetElement(1, 3, origin[1]); matrix->SetElement(2, 3, origin[2]); matrix->SetElement(3, 0, 0.0); matrix->SetElement(3, 1, 0.0); matrix->SetElement(3, 2, 0.0); matrix->SetElement(3, 3, 1.0); trans->SetMatrix(matrix); //Transform the camera to the current position (transveral, coronal and saggital plane). this->GetVtkRenderer()->GetActiveCamera()->ApplyTransform(trans); } } } diff --git a/Core/Code/Rendering/mitkVtkPropRenderer.h b/Core/Code/Rendering/mitkVtkPropRenderer.h index dc20875d88..47d69908c5 100644 --- a/Core/Code/Rendering/mitkVtkPropRenderer.h +++ b/Core/Code/Rendering/mitkVtkPropRenderer.h @@ -1,240 +1,239 @@ /*=================================================================== 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 MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D #define MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D #include #include "mitkBaseRenderer.h" #include "mitkDataStorage.h" #include "mitkRenderingManager.h" #include #include #include class vtkRenderWindow; class vtkLight; class vtkLightKit; class vtkWorldPointPicker; class vtkPointPicker; class vtkCellPicker; class vtkTextActor; class vtkTextProperty; class vtkAssemblyPath; namespace mitk { class Mapper; /*! \brief VtkPropRenderer VtkPropRenderer organizes the MITK rendering process. The MITK rendering process is completely integrated into the VTK rendering pipeline. The vtkMitkRenderProp is a custom vtkProp derived class, which implements the rendering interface between MITK and VTK. It redirects render() calls to the VtkPropRenderer, which is responsible for rendering of the datatreenodes. VtkPropRenderer replaces the old OpenGLRenderer. \sa rendering \ingroup rendering */ class MITK_CORE_EXPORT VtkPropRenderer : public BaseRenderer { // Workaround for Displaylistbug private: bool didCount; void checkState(); // Workaround END public: mitkClassMacro(VtkPropRenderer,BaseRenderer); mitkNewMacro3Param(VtkPropRenderer, const char*, vtkRenderWindow *, mitk::RenderingManager* ); typedef std::map MappersMapType; // Render - called by vtkMitkRenderProp, returns the number of props rendered enum RenderType{Opaque,Translucent,Overlay,Volumetric}; int Render(RenderType type); /** \brief This methods contains all method neceassary before a VTK Render() call */ virtual void PrepareRender(); // Active current renderwindow virtual void MakeCurrent(); virtual void SetDataStorage( mitk::DataStorage* storage ); ///< set the datastorage that will be used for rendering virtual void InitRenderer(vtkRenderWindow* renderwindow); virtual void Update(mitk::DataNode* datatreenode); virtual void SetMapperID(const MapperSlotId mapperId); // Size virtual void InitSize(int w, int h); virtual void Resize(int w, int h); // Picking enum PickingMode{ WorldPointPicking, PointPicking }; itkSetEnumMacro( PickingMode, PickingMode ); itkGetEnumMacro( PickingMode, PickingMode ); virtual void PickWorldPoint(const Point2D& displayPoint, Point3D& worldPoint) const; virtual mitk::DataNode *PickObject( const Point2D &displayPosition, Point3D &worldPosition ) const; // Simple text rendering method int WriteSimpleText(std::string text, double posX, double posY, double color1 = 0.0, double color2 = 1.0, double color3 = 0.0, float opacity = 1.0); vtkTextProperty * GetTextLabelProperty(int text_id); // Initialization / geometry handling /** This method calculates the bounds of the DataStorage (if it contains any * valid data), creates a geometry from these bounds and sets it as world * geometry of the renderer. * * Call this method to re-initialize the renderer to the current DataStorage * (e.g. after loading an additional dataset), to ensure that the view is * aligned correctly. */ virtual bool SetWorldGeometryToDataStorageBounds(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ void InitPathTraversal(); /** * \brief Used by vtkPointPicker/vtkPicker. * This will query a list of all objects in MITK and provide every vtk based mapper to the picker. */ vtkAssemblyPath* GetNextPath(); const vtkWorldPointPicker *GetWorldPointPicker() const; const vtkPointPicker *GetPointPicker() const; const vtkCellPicker *GetCellPicker() const; /** * \brief Release vtk-based graphics resources. Called by * vtkMitkRenderProp::ReleaseGraphicsResources. */ virtual void ReleaseGraphicsResources(vtkWindow *renWin); MappersMapType GetMappersMap() const; static bool useImmediateModeRendering(); protected: VtkPropRenderer( const char* name = "VtkPropRenderer", vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL ); virtual ~VtkPropRenderer(); virtual void Update(); private: /** \brief This method sets up the camera on the actor (e.g. an image) of all * 2D vtkRenderWindows. The view is centered; zooming and panning of VTK are called inside. * * \image html ImageMapperdisplayGeometry.png * * Similar to the textured plane of an image * (cf. void mitkImageVtkMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, * vtkFloatingPointType planeBounds[6])), the mitkDisplayGeometry defines a view plane (or * projection plane). This plane is used to set the camera parameters. The view plane * center (VC) is important for camera positioning (cf. the image above). * * The following figure shows the combination of the textured plane and the view plane. * * \image html cameraPositioning.png * * The view plane center (VC) is the center of the textured plane (C) and the focal point * (FP) at the same time. The FP defines the direction the camera faces. Since * the textured plane is always in the XY-plane and orthographic projection is applied, the * distance between camera and plane is theoretically irrelevant (because in the orthographic * projection the center of projection is at infinity and the size of objects depends only on * a scaling parameter). As a consequence, the direction of projection (DOP) is (0; 0; -1). * The camera up vector is always defined as (0; 1; 0). * * \warning Due to a VTK clipping bug the distance between textured plane and camera is really huge. * Otherwise, VTK would clip off some slices. Same applies for the clipping range size. * * \note The camera position is defined through the mitkDisplayGeometry. * This facilitates zooming and panning, because the display * geometry changes and the textured plane does not. * * \image html scaling.png * * The textured plane is scaled to fill the render window via * camera->SetParallelScale( imageHeightInMM / 2). In the orthographic projection all extends, * angles and sizes are preserved. Therefore, the image is scaled by one parameter which defines * the size of the rendered image. A higher value will result in smaller images. In order to render * just the whole image, the scale is set to half of the image height in worldcoordinates * (cf. the picture above). * * For zooming purposes, a factor is computed as follows: * factor = image height / display height (in worldcoordinates). * When the display geometry gets smaller (zoom in), the factor becomes bigger. When the display * geometry gets bigger (zoom out), the factor becomes smaller. The used VTK method * camera->Zoom( factor ) also works with an inverse scale. */ void AdjustCameraToScene(); // switch between orthogonal opengl projection (2D rendering via mitk::GLMapper2D) and perspective projection (3D rendering) void Enable2DOpenGL(); void Disable2DOpenGL(); // prepare all mitk::mappers for rendering void PrepareMapperQueue(); /** \brief Set parallel projection, remove the interactor and the lights of VTK. */ bool Initialize2DvtkCamera(); bool m_InitNeeded; bool m_ResizeNeeded; bool m_VtkMapperPresent; - bool m_NewRenderer; MapperSlotId m_CameraInitializedForMapperID; // Picking vtkWorldPointPicker * m_WorldPointPicker; vtkPointPicker * m_PointPicker; vtkCellPicker * m_CellPicker; PickingMode m_PickingMode; // Explicit use of SmartPointer to avoid circular #includes itk::SmartPointer< mitk::Mapper > m_CurrentWorldGeometry2DMapper; vtkLightKit* m_LightKit; // sorted list of mappers MappersMapType m_MappersMap; // rendering of text vtkRenderer * m_TextRenderer; typedef std::map TextMapType; TextMapType m_TextCollection; DataStorage::SetOfObjects::ConstPointer m_PickingObjects; DataStorage::SetOfObjects::const_iterator m_PickingObjectsIterator; }; } // namespace mitk #endif /* MITKVtkPropRenderer_H_HEADER_INCLUDED_C1C29F6D */ diff --git a/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp b/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp index d53739f41a..d12d23b1c4 100644 --- a/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp +++ b/Core/Code/Rendering/vtkMitkLevelWindowFilter.cpp @@ -1,597 +1,597 @@ /*=================================================================== 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 "vtkMitkLevelWindowFilter.h" #include #include #include #include //used for acos etc. #include //used for PI #include #include static const double PI = itk::Math::pi; vtkMitkLevelWindowFilter::vtkMitkLevelWindowFilter():m_MinOpacity(0.0),m_MaxOpacity(255.0) { //MITK_INFO << "mitk level/window filter uses " << GetNumberOfThreads() << " thread(s)"; } vtkMitkLevelWindowFilter::~vtkMitkLevelWindowFilter() { } unsigned long int vtkMitkLevelWindowFilter::GetMTime() { unsigned long mTime=this->vtkObject::GetMTime(); unsigned long time; if ( this->m_LookupTable != NULL ) { time = this->m_LookupTable->GetMTime(); mTime = ( time > mTime ? time : mTime ); } return mTime; } void vtkMitkLevelWindowFilter::SetLookupTable(vtkScalarsToColors *lookupTable) { if (m_LookupTable != lookupTable) { m_LookupTable = lookupTable; this->Modified(); } } vtkScalarsToColors* vtkMitkLevelWindowFilter::GetLookupTable() { return m_LookupTable; } //This code was copied from the iil. The template works only for float and double. //Internal method which should never be used anywhere else and should not be in th header. // Convert color pixels from (R,G,B) to (H,S,I). // Reference: "Digital Image Processing, 2nd. edition", R. Gonzalez and R. Woods. Prentice Hall, 2002. template void RGBtoHSI(T* RGB, T* HSI) { T R = RGB[0], G = RGB[1], B = RGB[2], nR = (R<0?0:(R>255?255:R))/255, nG = (G<0?0:(G>255?255:G))/255, nB = (B<0?0:(B>255?255:B))/255, m = nR0) H = (nB<=nG)?theta:360-theta; if (sum>0) S = 1 - 3/sum*m; I = sum/3; HSI[0] = (T)H; HSI[1] = (T)S; HSI[2] = (T)I; } //This code was copied from the iil. The template works only for float and double. //Internal method which should never be used anywhere else and should not be in th header. // Convert color pixels from (H,S,I) to (R,G,B). template void HSItoRGB(T* HSI, T* RGB) { T H = (T)HSI[0], S = (T)HSI[1], I = (T)HSI[2], a = I*(1-S), R = 0, G = 0, B = 0; if (H<120) { B = a; R = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180))); G = 3*I-(R+B); } else if (H<240) { H-=120; R = a; G = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180))); B = 3*I-(R+G); } else { H-=240; G = a; B = (T)(I*(1+S*std::cos(H*PI/180)/std::cos((60-H)*PI/180))); R = 3*I-(G+B); } R*=255; G*=255; B*=255; RGB[0] = (T)(R<0?0:(R>255?255:R)); RGB[1] = (T)(G<0?0:(G>255?255:G)); RGB[2] = (T)(B<0?0:(B>255?255:B)); } //Internal method which should never be used anywhere else and should not be in th header. //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template void vtkApplyLookupTableOnRGBA(vtkMitkLevelWindowFilter* self, vtkImageData* inData, vtkImageData* outData, int outExt[6], vtkFloatingPointType* clippingBounds, T*) { vtkImageIterator inputIt(inData, outExt); vtkImageIterator outputIt(outData, outExt); vtkLookupTable* lookupTable; const int maxC = inData->GetNumberOfScalarComponents(); double tableRange[2]; lookupTable = dynamic_cast(self->GetLookupTable()); lookupTable->GetTableRange(tableRange); //parameters for RGB level window double scale = (tableRange[1] -tableRange[0] > 0 ? 255.0 / (tableRange[1] - tableRange[0]) : 0.0); double bias = tableRange[0] * scale; //parameters for opaque level window double scaleOpac = (self->GetMaxOpacity() -self->GetMinOpacity() > 0 ? 255.0 / (self->GetMaxOpacity() - self->GetMinOpacity()) : 0.0); double biasOpac = self->GetMinOpacity() * scaleOpac; int y = outExt[2]; // Loop through ouput pixels while (!outputIt.IsAtEnd()) { T* inputSI = inputIt.BeginSpan(); T* outputSI = outputIt.BeginSpan(); T* outputSIEnd = outputIt.EndSpan(); if( y >= clippingBounds[2] && y < clippingBounds[3] ) { int x = outExt[0]; while (outputSI != outputSIEnd) { if ( x >= clippingBounds[0] && x < clippingBounds[1]) { double rgb[3], alpha, hsi[3]; // level/window mechanism for intensity in HSI space rgb[0] = static_cast(*inputSI); inputSI++; rgb[1] = static_cast(*inputSI); inputSI++; rgb[2] = static_cast(*inputSI); inputSI++; RGBtoHSI(rgb,hsi); hsi[2] = hsi[2] * 255.0 * scale - bias; hsi[2] = (hsi[2] > 255.0 ? 255 : (hsi[2] < 0.0 ? 0 : hsi[2])); hsi[2] /= 255.0; HSItoRGB(hsi,rgb); *outputSI = static_cast(rgb[0]); outputSI++; *outputSI = static_cast(rgb[1]); outputSI++; *outputSI = static_cast(rgb[2]); outputSI++; unsigned char finalAlpha = 255; //RGBA case if(maxC >= 4) { // level/window mechanism for opacity alpha = static_cast(*inputSI); inputSI++; alpha = alpha * scaleOpac - biasOpac; if(alpha > 255.0) { alpha = 255.0; } else if(alpha < 0.0) { alpha = 0.0; } - finalAlpha = static_cast(alpha); + finalAlpha = static_cast(alpha); for( int c = 4; c < maxC; c++ ) inputSI++; } *outputSI = static_cast(finalAlpha); outputSI++; } else { inputSI+=maxC; *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; } x++; } } else { while (outputSI != outputSIEnd) { *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; *outputSI = 0; outputSI++; } } inputIt.NextSpan(); outputIt.NextSpan(); y++; } } //Internal method which should never be used anywhere else and should not be in th header. //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template void vtkApplyLookupTableOnScalarsFast(vtkMitkLevelWindowFilter *self, vtkImageData *inData, vtkImageData *outData, int outExt[6], T *) { vtkImageIterator inputIt(inData, outExt); vtkImageIterator outputIt(outData, outExt); double tableRange[2]; // access vtkLookupTable vtkLookupTable* lookupTable = dynamic_cast(self->GetLookupTable()); lookupTable->GetTableRange(tableRange); // access elements of the vtkLookupTable int * realLookupTable = reinterpret_cast(lookupTable->GetTable()->GetPointer(0)); int maxIndex = lookupTable->GetNumberOfColors() - 1; float scale = (tableRange[1] -tableRange[0] > 0 ? (maxIndex + 1) / (tableRange[1] - tableRange[0]) : 0.0); // ensuring that starting point is zero float bias = - tableRange[0] * scale; // due to later conversion to int for rounding bias += 0.5f; // Loop through ouput pixels while (!outputIt.IsAtEnd()) { unsigned char* outputSI = outputIt.BeginSpan(); unsigned char* outputSIEnd = outputIt.EndSpan(); T* inputSI = inputIt.BeginSpan(); while (outputSI != outputSIEnd) { // map to an index int idx = static_cast( *inputSI * scale + bias ); if (idx < 0) idx = 0; else if (idx > maxIndex) idx = maxIndex; * reinterpret_cast(outputSI) = realLookupTable[idx]; inputSI++; outputSI+=4; } inputIt.NextSpan(); outputIt.NextSpan(); } } //Internal method which should never be used anywhere else and should not be in th header. //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template void vtkApplyLookupTableOnScalars(vtkMitkLevelWindowFilter *self, vtkImageData *inData, vtkImageData *outData, int outExt[6], vtkFloatingPointType* clippingBounds, T *) { vtkImageIterator inputIt(inData, outExt); vtkImageIterator outputIt(outData, outExt); vtkScalarsToColors* lookupTable = self->GetLookupTable(); int y = outExt[2]; // Loop through ouput pixels while (!outputIt.IsAtEnd()) { unsigned char* outputSI = outputIt.BeginSpan(); unsigned char* outputSIEnd = outputIt.EndSpan(); // do we iterate over the inner vertical clipping bounds if( y >= clippingBounds[2] && y < clippingBounds[3] ) { T* inputSI = inputIt.BeginSpan(); int x= outExt[0]; while (outputSI != outputSIEnd) { // is this pixel within horizontal clipping bounds if ( x >= clippingBounds[0] && x < clippingBounds[1]) { // fetching original value double grayValue = static_cast(*inputSI); // applying lookuptable - copy the 4 (RGBA) chars as a single int *reinterpret_cast(outputSI) = *reinterpret_cast(lookupTable->MapValue( grayValue )); } else { // outer horizontal clipping bounds - write a transparent RGBA pixel as a single int *reinterpret_cast(outputSI) = 0; } inputSI++; outputSI+=4; x++; } } else { // outer vertical clipping bounds - write a transparent RGBA line as ints while (outputSI != outputSIEnd) { *reinterpret_cast(outputSI) = 0; outputSI+=4; } } inputIt.NextSpan(); outputIt.NextSpan(); y++; } } //Internal method which should never be used anywhere else and should not be in th header. //---------------------------------------------------------------------------- // This templated function executes the filter for any type of data. template void vtkApplyLookupTableOnScalarsCTF(vtkMitkLevelWindowFilter *self, vtkImageData *inData, vtkImageData *outData, int outExt[6], vtkFloatingPointType* clippingBounds, T *) { vtkImageIterator inputIt(inData, outExt); vtkImageIterator outputIt(outData, outExt); vtkColorTransferFunction* lookupTable = dynamic_cast(self->GetLookupTable()); int y = outExt[2]; // Loop through ouput pixels while (!outputIt.IsAtEnd()) { unsigned char* outputSI = outputIt.BeginSpan(); unsigned char* outputSIEnd = outputIt.EndSpan(); // do we iterate over the inner vertical clipping bounds if( y >= clippingBounds[2] && y < clippingBounds[3] ) { T* inputSI = inputIt.BeginSpan(); int x= outExt[0]; while (outputSI != outputSIEnd) { // is this pixel within horizontal clipping bounds if ( x >= clippingBounds[0] && x < clippingBounds[1]) { // fetching original value double grayValue = static_cast(*inputSI); // applying directly colortransferfunction // because vtkColorTransferFunction::MapValue is not threadsafe double rgb[3]; lookupTable->GetColor( grayValue, rgb ); outputSI[0] = static_cast(255.0*rgb[0] + 0.5); outputSI[1] = static_cast(255.0*rgb[1] + 0.5); outputSI[2] = static_cast(255.0*rgb[2] + 0.5); outputSI[3] = 255; } else { // outer horizontal clipping bounds - write a transparent RGBA pixel as a single int *reinterpret_cast(outputSI) = 0; } inputSI++; outputSI+=4; x++; } } else { // outer vertical clipping bounds - write a transparent RGBA line as ints while (outputSI != outputSIEnd) { *reinterpret_cast(outputSI) = 0; outputSI+=4; } } inputIt.NextSpan(); outputIt.NextSpan(); y++; } } void vtkMitkLevelWindowFilter::ExecuteInformation() { vtkImageData *input = this->GetInput(); vtkImageData *output = this->GetOutput(); if (!input) { vtkErrorMacro(<< "Input not set."); return; } output->CopyTypeSpecificInformation( input ); // TODO make output RGBA output->SetScalarTypeToUnsignedChar(); output->SetNumberOfScalarComponents(4); int extent[6]; input->GetWholeExtent(extent); output->SetExtent(extent); output->SetWholeExtent(extent); output->SetUpdateExtent(extent); output->AllocateScalars(); } //Method to run the filter in different threads. void vtkMitkLevelWindowFilter::ThreadedExecute(vtkImageData *inData, vtkImageData *outData, int extent[6], int /*id*/) { if(inData->GetNumberOfScalarComponents() > 2) { switch (inData->GetScalarType()) { vtkTemplateMacro( vtkApplyLookupTableOnRGBA( this, inData, outData, extent, m_ClippingBounds, static_cast(0))); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } else { bool dontClip = extent[2] >= m_ClippingBounds[2] && extent[3] <= m_ClippingBounds[3] && extent[0] >= m_ClippingBounds[0] && extent[1] <= m_ClippingBounds[1]; if(this->GetLookupTable()) this->GetLookupTable()->Build(); vtkLookupTable *vlt = dynamic_cast(this->GetLookupTable()); vtkColorTransferFunction *ctf = dynamic_cast(this->GetLookupTable()); bool linearLookupTable = vlt && vlt->GetScale() == VTK_SCALE_LINEAR; bool useFast = dontClip && linearLookupTable; if(ctf) { switch (inData->GetScalarType()) { vtkTemplateMacro( vtkApplyLookupTableOnScalarsCTF( this, inData, outData, extent, m_ClippingBounds, static_cast(0))); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } else if(useFast) { switch (inData->GetScalarType()) { vtkTemplateMacro( vtkApplyLookupTableOnScalarsFast( this, inData, outData, extent, static_cast(0))); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } else { switch (inData->GetScalarType()) { vtkTemplateMacro( vtkApplyLookupTableOnScalars( this, inData, outData, extent, m_ClippingBounds, static_cast(0))); default: vtkErrorMacro(<< "Execute: Unknown ScalarType"); return; } } } } void vtkMitkLevelWindowFilter::ExecuteInformation( vtkImageData *vtkNotUsed(inData), vtkImageData *vtkNotUsed(outData)) { } void vtkMitkLevelWindowFilter::SetMinOpacity(double minOpacity) { m_MinOpacity = minOpacity; } inline double vtkMitkLevelWindowFilter::GetMinOpacity() const { return m_MinOpacity; } void vtkMitkLevelWindowFilter::SetMaxOpacity(double maxOpacity) { m_MaxOpacity = maxOpacity; } inline double vtkMitkLevelWindowFilter::GetMaxOpacity() const { return m_MaxOpacity; } void vtkMitkLevelWindowFilter::SetClippingBounds(vtkFloatingPointType* bounds) // TODO does vtkFloatingPointType[4] work?? { for (unsigned int i = 0 ; i < 4; ++i) m_ClippingBounds[i] = bounds[i]; } diff --git a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox index a80b2c16f6..ca31f1bb1b 100644 --- a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox +++ b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox @@ -1,41 +1,42 @@ /** \page PluginListPage MITK Plugin Manuals \section PluginListPageOverview Overview The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed. The distinction between developer and end user use is for convenience only and mainly distinguishes which group a plugin is primarily aimed at. \section PluginListPageEndUserPluginList List of Plugins for End User Use \li \subpage org_blueberry_ui_qt_log \li \subpage org_mitk_views_basicimageprocessing + \li \subpage org_mitk_views_cmdlinemodules \li \subpage org_mitk_views_datamanager \li \subpage org_mitk_gui_qt_diffusionimaging \li \subpage org_mitk_views_imagecropper \li \subpage org_mitk_views_imagenavigator \li \subpage org_mitk_gui_qt_measurementtoolbox \li \subpage org_mitk_views_moviemaker \li \subpage org_mitk_views_meshdecimation \li \subpage org_mitk_views_pointsetinteraction \li \subpage org_mitk_gui_qt_registration \li \subpage org_mitk_views_segmentation \li \subpage org_mitk_views_volumevisualization \li \subpage org_mitk_gui_qt_dicom \li \subpage org_mitk_gui_qt_ultrasound \li \subpage org_mitk_views_fiberfoxview \section PluginListPageDevPluginList List of Plugins for Developer Use and Examples \li \subpage org_surfacematerialeditor \li \subpage org_toftutorial \li \subpage org_mitk_gui_qt_examples \li \subpage org_mitkexamplesopencv \li \ref org_mitk_gui_qt_igtexample \li \ref org_mitk_gui_qt_igttracking \li \subpage org_blueberry_ui_qt_objectinspector \li \subpage org_mitk_gui_InteractionTests */ diff --git a/Documentation/Doxygen/UserManual/UserManualPortal.dox b/Documentation/Doxygen/UserManual/UserManualPortal.dox index 83d3a73e5b..bca8c867fe 100644 --- a/Documentation/Doxygen/UserManual/UserManualPortal.dox +++ b/Documentation/Doxygen/UserManual/UserManualPortal.dox @@ -1,9 +1,14 @@ /** \page UserManualPortal MITK: User Manual +Due to the modular architecture of MITK the user documentation is split in different parts. You can find a short description of the intended purpose and audience of MITK based applications developed by us at \ref ApplicationsPage. To get an introduction into the usage of any MITK based application please read \ref MITKUserManualPage. It will give you an overview of most of the common questions, such as how to load or save data or navigate within it. + +For any more specific documentation of how a plugin operates you can find the plugin documentation in \ref PluginListPage. Depending on the application you are using you might have only some or all of the listed plugins available. + +\section UserManualPortalTopics List of topics
  • \subpage ApplicationsPage
  • \subpage MITKUserManualPage
  • \subpage PluginListPage
*/ \ No newline at end of file diff --git a/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx b/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx index 99c03a49f2..c59f9e0976 100644 --- a/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx +++ b/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx @@ -1,156 +1,141 @@ /*=================================================================== 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 "mitkImageRegistrationMethodAccessFunctor.h" #include "mitkImageRegistrationMethod.h" #include #include namespace mitk { template void ImageRegistrationMethodAccessFunctor::AccessItkImage(itk::Image* itkImage1, ImageRegistrationMethod* method) { //convert mitk masks to itk masks typedef typename itk::Image FixedImageType; typedef typename itk::Image MovingImageType; typedef typename itk::Image< unsigned char, VImageDimension > MaskImageType; typedef typename itk::ImageMaskSpatialObject< VImageDimension > ImageMaskType; typename ImageMaskType::Pointer movingImageMask; if(method->m_MovingMask.IsNotNull()) { typename MovingImageType::Pointer movingMask = MovingImageType::New(); mitk::CastToItkImage(method->m_MovingMask, movingMask); typename itk::CastImageFilter::Pointer maskImageCaster = itk::CastImageFilter::New(); maskImageCaster->SetInput(movingMask); maskImageCaster->UpdateLargestPossibleRegion(); movingImageMask = ImageMaskType::New(); movingImageMask->SetImage(maskImageCaster->GetOutput()); } typename ImageMaskType::Pointer fixedImageMask; if(method->m_FixedMask.IsNotNull()) { typename FixedImageType::Pointer fixedMask = FixedImageType::New(); mitk::CastToItkImage(method->m_FixedMask, fixedMask); typename itk::CastImageFilter::Pointer maskImageCaster = itk::CastImageFilter::New(); maskImageCaster->SetInput(fixedMask); maskImageCaster->UpdateLargestPossibleRegion(); fixedImageMask = ImageMaskType::New(); fixedImageMask->SetImage(maskImageCaster->GetOutput()); } // typedefs typedef typename itk::Image FixedImageType; typedef typename itk::Image MovingImageType; typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef typename itk::ImageRegistrationMethod RegistrationType; - typedef typename itk::Transform< double, VImageDimension, VImageDimension > TransformType; + typedef typename itk::MatrixOffsetTransformBase< double, VImageDimension, VImageDimension > TransformType; typedef typename TransformType::Pointer TransformPointer; typedef typename itk::ImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointer; typedef typename itk::SingleValuedNonLinearOptimizer OptimizerType; // the fixed and the moving image typename FixedImageType::Pointer fixedImage = FixedImageType::New(); typename MovingImageType::Pointer movingImage = itkImage1; mitk::CastToItkImage(method->m_ReferenceImage, fixedImage); // the metric MetricPointer metric = dynamic_cast(method->m_Metric.GetPointer()); if(movingImageMask.IsNotNull()) metric->SetMovingImageMask(movingImageMask); if(fixedImageMask.IsNotNull()) metric->SetFixedImageMask(fixedImageMask); // the transform TransformPointer transform = dynamic_cast(method->m_Transform.GetPointer()); // the optimizer typename OptimizerType::Pointer optimizer = dynamic_cast(method->m_Optimizer.GetPointer()); // optimizer scales if (method->m_OptimizerScales.Size() != 0) { typename OptimizerType::ScalesType scales( transform->GetNumberOfParameters() ); for (unsigned int i = 0; i < scales.Size(); i++) { scales[i] = method->m_OptimizerScales[i]; } optimizer->SetScales( scales ); } // the registration method typename RegistrationType::Pointer registration = RegistrationType::New(); registration->SetMetric(metric); registration->SetOptimizer(optimizer); registration->SetTransform(transform); registration->SetFixedImage(fixedImage); registration->SetMovingImage(movingImage); registration->SetFixedImageRegion(fixedImage->GetBufferedRegion()); -// if(transFac->GetTransformParameters()->GetInitialParameters().size()) -// { -// registration->SetInitialTransformParameters( transFac->GetTransformParameters()->GetInitialParameters() ); -// } -// else -// { - itk::Array zeroInitial; - zeroInitial.set_size(transform->GetNumberOfParameters()); - zeroInitial.fill(0.0); - if (zeroInitial.size() >= 1) - { - zeroInitial[0] = 1.0; - } - if (zeroInitial.size() >= 5) - { - zeroInitial[4] = 1.0; - } - if (zeroInitial.size() >= 9) - { - zeroInitial[8] = 1.0; - } - registration->SetInitialTransformParameters( zeroInitial ); - optimizer->SetInitialPosition( zeroInitial ); -// } + + // set initial position to identity by first setting the transformation to identity + // and then using its parameters + transform->SetIdentity(); + typename TransformType::ParametersType identityParameters = transform->GetParameters(); + + registration->SetInitialTransformParameters( identityParameters ); + optimizer->SetInitialPosition( identityParameters ); + if (method->m_Interpolator == ImageRegistrationMethod::LINEARINTERPOLATOR) { typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); registration->SetInterpolator(interpolator); } else if (method->m_Interpolator == ImageRegistrationMethod::NEARESTNEIGHBORINTERPOLATOR) { typename InterpolatorType2::Pointer interpolator = InterpolatorType2::New(); registration->SetInterpolator(interpolator); } // registering command observer with the optimizer if (method->m_Observer.IsNotNull()) { method->m_Observer->AddStepsToDo(20); optimizer->AddObserver(itk::AnyEvent(), method->m_Observer); registration->AddObserver(itk::AnyEvent(), method->m_Observer); transform->AddObserver(itk::AnyEvent(), method->m_Observer); } registration->Update(); if (method->m_Observer.IsNotNull()) { optimizer->RemoveAllObservers(); registration->RemoveAllObservers(); transform->RemoveAllObservers(); method->m_Observer->SetRemainingProgress(15); } if (method->m_Observer.IsNotNull()) { method->m_Observer->SetRemainingProgress(5); } } } // end namespace diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkAffineTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkAffineTransformView.cpp index 9e261e2fe9..8e175cbf65 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkAffineTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkAffineTransformView.cpp @@ -1,258 +1,264 @@ /*=================================================================== 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 "QmitkAffineTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkAffineTransformView::QmitkAffineTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkAffineTransformView::~QmitkAffineTransformView() { } mitk::TransformParameters::TransformType QmitkAffineTransformView::GetTransformType() { return mitk::TransformParameters::AFFINETRANSFORM; } itk::Object::Pointer QmitkAffineTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { AccessByItk(m_FixedImage, GetTransform2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkAffineTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkAffineTransformView::GetTransform2(itk::Image* itkImage1) { typedef typename itk::Image< TPixelType, VImageDimension > FixedImageType; typedef typename itk::Image< TPixelType, VImageDimension > MovingImageType; - typename FixedImageType::Pointer fixedImage; - mitk::CastToItkImage(m_FixedImage, fixedImage); - typename MovingImageType::Pointer movingImage; - mitk::CastToItkImage(m_MovingImage, movingImage); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImageType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImageType::Pointer movingImage = movingImageToItk->GetOutput(); + typename itk::AffineTransform< double, VImageDimension>::Pointer transformPointer = itk::AffineTransform< double, VImageDimension>::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerAffine->isChecked()) { typedef typename itk::AffineTransform< double, VImageDimension > AffineTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage ); transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsAffine->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } itk::Array QmitkAffineTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(15); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesAffine->isChecked(); transformValues[1] = m_Controls.m_ScalesAffineTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesAffineTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesAffineTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesAffineTransformScale4->text().toDouble(); transformValues[5] = m_Controls.m_ScalesAffineTransformScale5->text().toDouble(); transformValues[6] = m_Controls.m_ScalesAffineTransformScale6->text().toDouble(); transformValues[7] = m_Controls.m_ScalesAffineTransformScale7->text().toDouble(); transformValues[8] = m_Controls.m_ScalesAffineTransformScale8->text().toDouble(); transformValues[9] = m_Controls.m_ScalesAffineTransformScale9->text().toDouble(); transformValues[10] = m_Controls.m_ScalesAffineTransformScaleTranslationX->text().toDouble(); transformValues[11] = m_Controls.m_ScalesAffineTransformScaleTranslationY->text().toDouble(); transformValues[12] = m_Controls.m_ScalesAffineTransformScaleTranslationZ->text().toDouble(); transformValues[13] = m_Controls.m_CenterForInitializerAffine->isChecked(); transformValues[14] = m_Controls.m_MomentsAffine->isChecked(); return transformValues; } void QmitkAffineTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesAffine->setChecked(transformValues[0]); m_Controls.m_ScalesAffineTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesAffineTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesAffineTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesAffineTransformScale4->setText(QString::number(transformValues[4])); m_Controls.m_ScalesAffineTransformScale5->setText(QString::number(transformValues[5])); m_Controls.m_ScalesAffineTransformScale6->setText(QString::number(transformValues[6])); m_Controls.m_ScalesAffineTransformScale7->setText(QString::number(transformValues[7])); m_Controls.m_ScalesAffineTransformScale8->setText(QString::number(transformValues[8])); m_Controls.m_ScalesAffineTransformScale9->setText(QString::number(transformValues[9])); m_Controls.m_ScalesAffineTransformScaleTranslationX->setText(QString::number(transformValues[10])); m_Controls.m_ScalesAffineTransformScaleTranslationY->setText(QString::number(transformValues[11])); m_Controls.m_ScalesAffineTransformScaleTranslationZ->setText(QString::number(transformValues[12])); m_Controls.m_CenterForInitializerAffine->setChecked(transformValues[13]); m_Controls.m_MomentsAffine->setChecked(transformValues[14]); m_Controls.m_GeometryAffine->setChecked(!transformValues[14]); } QString QmitkAffineTransformView::GetName() { return "Affine"; } void QmitkAffineTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesAffineTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale4->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale5->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale6->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale7->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale8->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScale9->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesAffineTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); } itk::Array QmitkAffineTransformView::GetScales() { itk::Array scales; scales.SetSize(12); scales.Fill(1.0); scales[0] = m_Controls.m_ScalesAffineTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesAffineTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesAffineTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesAffineTransformScale4->text().toDouble(); scales[4] = m_Controls.m_ScalesAffineTransformScale5->text().toDouble(); scales[5] = m_Controls.m_ScalesAffineTransformScale6->text().toDouble(); scales[6] = m_Controls.m_ScalesAffineTransformScale7->text().toDouble(); scales[7] = m_Controls.m_ScalesAffineTransformScale8->text().toDouble(); scales[8] = m_Controls.m_ScalesAffineTransformScale9->text().toDouble(); scales[9] = m_Controls.m_ScalesAffineTransformScaleTranslationX->text().toDouble(); scales[10] = m_Controls.m_ScalesAffineTransformScaleTranslationY->text().toDouble(); scales[11] = m_Controls.m_ScalesAffineTransformScaleTranslationZ->text().toDouble(); return scales; } vtkTransform* QmitkAffineTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { // - the 9 rotation-coefficients are copied // directly to the top left part of the matrix int m = 0; for (unsigned int i = 0; i < m_FixedImage->GetDimension(); i++) { for (unsigned int j = 0; j < m_FixedImage->GetDimension(); j++) { vtkmatrix->SetElement(i, j, transformParams[m]); m++; } } // - the 3 translation-coefficients are corrected to take // into account the center of the transformation float center[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; std::cout<< "rotation center: " << center[0] << " " << center[1] << " " << center [2] << std::endl; float translation[4]; vtkmatrix->MultiplyPoint(center, translation); if (m_FixedImage->GetDimension() == 2) { vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[4]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[5]); } else if (m_FixedImage->GetDimension() == 3) { vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[9]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[10]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[11]); } // set the transform matrix to init the transform vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkAffineTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) { m_Controls.m_ScalesAffineTransformScale7->hide(); m_Controls.m_ScalesAffineTransformScale8->hide(); m_Controls.m_ScalesAffineTransformScale9->hide(); m_Controls.m_ScalesAffineTransformScaleTranslationX->hide(); m_Controls.m_ScalesAffineTransformScaleTranslationY->hide(); m_Controls.m_ScalesAffineTransformScaleTranslationZ->hide(); m_Controls.textLabel2_7->setText("Translation Scale X:"); m_Controls.textLabel3_6->setText("Translation Scale Y:"); m_Controls.textLabel4_4->hide(); m_Controls.textLabel5_4->hide(); m_Controls.textLabel6_4->hide(); m_Controls.textLabel11_3->hide(); m_Controls.textLabel12_3->hide(); m_Controls.textLabel13_2->hide(); return 6; } else { m_Controls.m_ScalesAffineTransformScale7->show(); m_Controls.m_ScalesAffineTransformScale8->show(); m_Controls.m_ScalesAffineTransformScale9->show(); m_Controls.m_ScalesAffineTransformScaleTranslationX->show(); m_Controls.m_ScalesAffineTransformScaleTranslationY->show(); m_Controls.m_ScalesAffineTransformScaleTranslationZ->show(); m_Controls.textLabel2_7->setText("Scale 5:"); m_Controls.textLabel3_6->setText("Scale 6:"); m_Controls.textLabel4_4->show(); m_Controls.textLabel5_4->show(); m_Controls.textLabel6_4->show(); m_Controls.textLabel11_3->show(); m_Controls.textLabel12_3->show(); m_Controls.textLabel13_2->show(); return 12; } } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredRigid2DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredRigid2DTransformView.cpp index f3b844d2ed..1789631ecf 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredRigid2DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredRigid2DTransformView.cpp @@ -1,178 +1,185 @@ /*=================================================================== 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 "QmitkCenteredRigid2DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkCenteredRigid2DTransformView::QmitkCenteredRigid2DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkCenteredRigid2DTransformView::~QmitkCenteredRigid2DTransformView() { } mitk::TransformParameters::TransformType QmitkCenteredRigid2DTransformView::GetTransformType() { return mitk::TransformParameters::CENTEREDRIGID2DTRANSFORM; } itk::Object::Pointer QmitkCenteredRigid2DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkCenteredRigid2DTransformView::GetTransform2(itk::Image* /* itkImage1 */) +itk::Object::Pointer QmitkCenteredRigid2DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 2) { typedef typename itk::Image< TPixelType, 2 > FixedImage2DType; typedef typename itk::Image< TPixelType, 2 > MovingImage2DType; - typename FixedImage2DType::Pointer fixedImage2D; - mitk::CastToItkImage(m_FixedImage, fixedImage2D); - typename MovingImage2DType::Pointer movingImage2D; - mitk::CastToItkImage(m_MovingImage, movingImage2D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage2DType::Pointer fixedImage2D = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = + mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage2DType::Pointer movingImage2D = movingImageToItk->GetOutput(); + typename itk::CenteredRigid2DTransform< double >::Pointer transformPointer = itk::CenteredRigid2DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerCenteredRigid2D->isChecked()) { typedef typename itk::CenteredRigid2DTransform< double > CenteredRigid2DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage2D ); transformInitializer->SetMovingImage( movingImage2D ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsCenteredRigid2D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } transformPointer->SetAngle( m_Controls.m_AngleCenteredRigid2D->text().toFloat() ); m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkCenteredRigid2DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(9); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesCenteredRigid2D->isChecked(); transformValues[1] = m_Controls.m_RotationScaleCenteredRigid2D->text().toDouble(); transformValues[2] = m_Controls.m_CenterXScaleCenteredRigid2D->text().toDouble(); transformValues[3] = m_Controls.m_CenterYScaleCenteredRigid2D->text().toDouble(); transformValues[4] = m_Controls.m_TranslationXScaleCenteredRigid2D->text().toDouble(); transformValues[5] = m_Controls.m_TranslationYScaleCenteredRigid2D->text().toDouble(); transformValues[6] = m_Controls.m_AngleCenteredRigid2D->text().toFloat(); transformValues[7] = m_Controls.m_CenterForInitializerCenteredRigid2D->isChecked(); transformValues[8] = m_Controls.m_MomentsCenteredRigid2D->isChecked(); return transformValues; } void QmitkCenteredRigid2DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesCenteredRigid2D->setChecked(transformValues[0]); m_Controls.m_RotationScaleCenteredRigid2D->setText(QString::number(transformValues[1])); m_Controls.m_CenterXScaleCenteredRigid2D->setText(QString::number(transformValues[2])); m_Controls.m_CenterYScaleCenteredRigid2D->setText(QString::number(transformValues[3])); m_Controls.m_TranslationXScaleCenteredRigid2D->setText(QString::number(transformValues[4])); m_Controls.m_TranslationYScaleCenteredRigid2D->setText(QString::number(transformValues[5])); m_Controls.m_AngleCenteredRigid2D->setText(QString::number(transformValues[6])); m_Controls.m_CenterForInitializerCenteredRigid2D->setChecked(transformValues[7]); m_Controls.m_MomentsCenteredRigid2D->setChecked(transformValues[8]); m_Controls.m_GeometryCenteredRigid2D->setChecked(!transformValues[8]); } QString QmitkCenteredRigid2DTransformView::GetName() { return "CenteredRigid2D"; } void QmitkCenteredRigid2DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_AngleCenteredRigid2D->setValidator(validatorLineEditInputFloat); m_Controls.m_RotationScaleCenteredRigid2D->setValidator(validatorLineEditInputFloat); m_Controls.m_CenterXScaleCenteredRigid2D->setValidator(validatorLineEditInputFloat); m_Controls.m_CenterYScaleCenteredRigid2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationXScaleCenteredRigid2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationYScaleCenteredRigid2D->setValidator(validatorLineEditInputFloat); } itk::Array QmitkCenteredRigid2DTransformView::GetScales() { itk::Array scales; scales.SetSize(5); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesCenteredRigid2D->isChecked()) { scales[0] = m_Controls.m_RotationScaleCenteredRigid2D->text().toDouble(); scales[1] = m_Controls.m_CenterXScaleCenteredRigid2D->text().toDouble(); scales[2] = m_Controls.m_CenterYScaleCenteredRigid2D->text().toDouble(); scales[3] = m_Controls.m_TranslationXScaleCenteredRigid2D->text().toDouble(); scales[4] = m_Controls.m_TranslationYScaleCenteredRigid2D->text().toDouble(); } return scales; } vtkTransform* QmitkCenteredRigid2DTransformView::Transform(vtkMatrix4x4* /* vtkmatrix */, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { mitk::ScalarType angle = transformParams[0] * 45.0 / atan(1.0);; vtktransform->PostMultiply(); vtktransform->Translate(-transformParams[1], -transformParams[2], 0); vtktransform->RotateZ(angle); vtktransform->Translate(transformParams[1], transformParams[2], 0); vtktransform->Translate(transformParams[3], transformParams[4], 0); vtktransform->PreMultiply(); } return vtktransform; } int QmitkCenteredRigid2DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 5; else return 0; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredSimilarity2DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredSimilarity2DTransformView.cpp index fe248a4aaf..4d052e4ad9 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredSimilarity2DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkCenteredSimilarity2DTransformView.cpp @@ -1,186 +1,192 @@ /*=================================================================== 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 "QmitkCenteredSimilarity2DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkCenteredSimilarity2DTransformView::QmitkCenteredSimilarity2DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkCenteredSimilarity2DTransformView::~QmitkCenteredSimilarity2DTransformView() { } mitk::TransformParameters::TransformType QmitkCenteredSimilarity2DTransformView::GetTransformType() { return mitk::TransformParameters::CENTEREDSIMILARITY2DTRANSFORM; } itk::Object::Pointer QmitkCenteredSimilarity2DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkCenteredSimilarity2DTransformView::GetTransform2(itk::Image* /* itkImage1 */) +itk::Object::Pointer QmitkCenteredSimilarity2DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 2) { typedef typename itk::Image< TPixelType, 2 > FixedImage2DType; typedef typename itk::Image< TPixelType, 2 > MovingImage2DType; - typename FixedImage2DType::Pointer fixedImage2D; - mitk::CastToItkImage(m_FixedImage, fixedImage2D); - typename MovingImage2DType::Pointer movingImage2D; - mitk::CastToItkImage(m_MovingImage, movingImage2D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage2DType::Pointer fixedImage2D = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = + mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage2DType::Pointer movingImage2D = movingImageToItk->GetOutput(); typename itk::CenteredSimilarity2DTransform< double >::Pointer transformPointer = itk::CenteredSimilarity2DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerCenteredSimilarity2D->isChecked()) { typedef typename itk::CenteredSimilarity2DTransform< double > CenteredSimilarity2DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage2D ); transformInitializer->SetMovingImage( movingImage2D ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsCenteredSimilarity2D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } transformPointer->SetScale( m_Controls.m_InitialScaleCenteredSimilarity2D->text().toFloat() ); transformPointer->SetAngle( m_Controls.m_AngleCenteredSimilarity2D->text().toFloat() ); m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkCenteredSimilarity2DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(11); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesCenteredSimilarity2D->isChecked(); transformValues[1] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale4->text().toDouble(); transformValues[5] = m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationX->text().toDouble(); transformValues[6] = m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationY->text().toDouble(); transformValues[7] = m_Controls.m_InitialScaleCenteredSimilarity2D->text().toFloat(); transformValues[8] = m_Controls.m_AngleCenteredSimilarity2D->text().toFloat(); transformValues[9] = m_Controls.m_CenterForInitializerCenteredSimilarity2D->isChecked(); transformValues[10] = m_Controls.m_MomentsCenteredSimilarity2D->isChecked(); return transformValues; } void QmitkCenteredSimilarity2DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesCenteredSimilarity2D->setChecked(transformValues[0]); m_Controls.m_ScalesCenteredSimilarity2DTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesCenteredSimilarity2DTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesCenteredSimilarity2DTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesCenteredSimilarity2DTransformScale4->setText(QString::number(transformValues[4])); m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationX->setText(QString::number(transformValues[5])); m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationY->setText(QString::number(transformValues[6])); m_Controls.m_InitialScaleCenteredSimilarity2D->setText(QString::number(transformValues[7])); m_Controls.m_AngleCenteredSimilarity2D->setText(QString::number(transformValues[8])); m_Controls.m_CenterForInitializerCenteredSimilarity2D->setChecked(transformValues[9]); m_Controls.m_MomentsCenteredSimilarity2D->setChecked(transformValues[10]); m_Controls.m_GeometryCenteredSimilarity2D->setChecked(!transformValues[10]); } QString QmitkCenteredSimilarity2DTransformView::GetName() { return "CenteredSimilarity2D"; } void QmitkCenteredSimilarity2DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesCenteredSimilarity2DTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesCenteredSimilarity2DTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesCenteredSimilarity2DTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesCenteredSimilarity2DTransformScale4->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); } itk::Array QmitkCenteredSimilarity2DTransformView::GetScales() { itk::Array scales; scales.SetSize(6); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesCenteredSimilarity2D->isChecked()) { scales[0] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesCenteredSimilarity2DTransformScale4->text().toDouble(); scales[4] = m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationX->text().toDouble(); scales[5] = m_Controls.m_ScalesCenteredSimilarity2DTransformScaleTranslationY->text().toDouble(); } return scales; } vtkTransform* QmitkCenteredSimilarity2DTransformView::Transform(vtkMatrix4x4* /*vtkmatrix*/, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { mitk::ScalarType angle = transformParams[1] * 45.0 / atan(1.0); vtktransform->PostMultiply(); vtktransform->Translate(-transformParams[2], -transformParams[3], 0); vtktransform->Scale(transformParams[0], transformParams[0], 1); vtktransform->RotateZ(angle); vtktransform->Translate(transformParams[2], transformParams[3], 0); vtktransform->Translate(transformParams[4], transformParams[5], 0); vtktransform->PreMultiply(); } return vtktransform; } int QmitkCenteredSimilarity2DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 6; else return 0; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkEuler2DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkEuler2DTransformView.cpp index 9b89d7c7a8..aaa6a8f174 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkEuler2DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkEuler2DTransformView.cpp @@ -1,162 +1,169 @@ /*=================================================================== 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 "QmitkEuler2DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkEuler2DTransformView::QmitkEuler2DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkEuler2DTransformView::~QmitkEuler2DTransformView() { } mitk::TransformParameters::TransformType QmitkEuler2DTransformView::GetTransformType() { return mitk::TransformParameters::EULER2DTRANSFORM; } itk::Object::Pointer QmitkEuler2DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkEuler2DTransformView::GetTransform2(itk::Image* /* itkImage1 */) +itk::Object::Pointer QmitkEuler2DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 2) { typedef typename itk::Image< TPixelType, 2 > FixedImage2DType; typedef typename itk::Image< TPixelType, 2 > MovingImage2DType; - typename FixedImage2DType::Pointer fixedImage2D; - mitk::CastToItkImage(m_FixedImage, fixedImage2D); - typename MovingImage2DType::Pointer movingImage2D; - mitk::CastToItkImage(m_MovingImage, movingImage2D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage2DType::Pointer fixedImage2D = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = + mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage2DType::Pointer movingImage2D = movingImageToItk->GetOutput(); + typename itk::Euler2DTransform< double >::Pointer transformPointer = itk::Euler2DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerEuler2D->isChecked()) { typedef typename itk::Euler2DTransform< double > Euler2DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage2D ); transformInitializer->SetMovingImage( movingImage2D ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsEuler2D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkEuler2DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(6); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesEuler2D->isChecked(); transformValues[1] = m_Controls.m_RotationScaleEuler2D->text().toDouble(); transformValues[2] = m_Controls.m_TranslationXScaleEuler2D->text().toDouble(); transformValues[3] = m_Controls.m_TranslationYScaleEuler2D->text().toDouble(); transformValues[4] = m_Controls.m_CenterForInitializerEuler2D->isChecked(); transformValues[5] = m_Controls.m_MomentsEuler2D->isChecked(); return transformValues; } void QmitkEuler2DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesEuler2D->setChecked(transformValues[0]); m_Controls.m_RotationScaleEuler2D->setText(QString::number(transformValues[1])); m_Controls.m_TranslationXScaleEuler2D->setText(QString::number(transformValues[2])); m_Controls.m_TranslationYScaleEuler2D->setText(QString::number(transformValues[3])); m_Controls.m_CenterForInitializerEuler2D->setChecked(transformValues[4]); m_Controls.m_MomentsEuler2D->setChecked(transformValues[5]); m_Controls.m_GeometryEuler2D->setChecked(!transformValues[5]); } QString QmitkEuler2DTransformView::GetName() { return "Euler2D"; } void QmitkEuler2DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_RotationScaleEuler2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationXScaleEuler2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationYScaleEuler2D->setValidator(validatorLineEditInputFloat); } itk::Array QmitkEuler2DTransformView::GetScales() { itk::Array scales; scales.SetSize(3); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesEuler2D->isChecked()) { scales[0] = m_Controls.m_RotationScaleEuler2D->text().toDouble(); scales[1] = m_Controls.m_TranslationXScaleEuler2D->text().toDouble(); scales[2] = m_Controls.m_TranslationYScaleEuler2D->text().toDouble(); } return scales; } vtkTransform* QmitkEuler2DTransformView::Transform(vtkMatrix4x4* /*vtkmatrix*/, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { mitk::ScalarType angle = transformParams[0] * 45.0 / atan(1.0); vtktransform->PostMultiply(); vtktransform->RotateZ(angle); vtktransform->Translate(transformParams[1], transformParams[2], 0); vtktransform->PreMultiply(); } return vtktransform; } int QmitkEuler2DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 3; else return 0; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkFixedCenterOfRotationAffineTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkFixedCenterOfRotationAffineTransformView.cpp index 966081f3c3..82f63f32fd 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkFixedCenterOfRotationAffineTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkFixedCenterOfRotationAffineTransformView.cpp @@ -1,253 +1,259 @@ /*=================================================================== 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 "QmitkFixedCenterOfRotationAffineTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkFixedCenterOfRotationAffineTransformView::QmitkFixedCenterOfRotationAffineTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkFixedCenterOfRotationAffineTransformView::~QmitkFixedCenterOfRotationAffineTransformView() { } mitk::TransformParameters::TransformType QmitkFixedCenterOfRotationAffineTransformView::GetTransformType() { return mitk::TransformParameters::FIXEDCENTEROFROTATIONAFFINETRANSFORM; } itk::Object::Pointer QmitkFixedCenterOfRotationAffineTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { AccessByItk(m_FixedImage, GetTransform2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkFixedCenterOfRotationAffineTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkFixedCenterOfRotationAffineTransformView::GetTransform2(itk::Image* itkImage1) { typedef typename itk::Image< TPixelType, VImageDimension > FixedImageType; typedef typename itk::Image< TPixelType, VImageDimension > MovingImageType; - typename FixedImageType::Pointer fixedImage; - mitk::CastToItkImage(m_FixedImage, fixedImage); - typename MovingImageType::Pointer movingImage; - mitk::CastToItkImage(m_MovingImage, movingImage); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImageType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImageType::Pointer movingImage = movingImageToItk->GetOutput(); + typedef typename itk::FixedCenterOfRotationAffineTransform< double, VImageDimension > CenteredAffineTransformType; typename itk::FixedCenterOfRotationAffineTransform< double, VImageDimension>::Pointer transformPointer = itk::FixedCenterOfRotationAffineTransform< double, VImageDimension>::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerFixedCenterOfRotationAffine->isChecked()) { typedef typename itk::FixedCenterOfRotationAffineTransform< double, VImageDimension > FixedCenterOfRotationAffineTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage ); transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsFixedCenterOfRotationAffine->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; transformInitializer->InitializeTransform(); } m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } itk::Array QmitkFixedCenterOfRotationAffineTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(15); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesFixedCenterOfRotationAffine->isChecked(); transformValues[1] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale4->text().toDouble(); transformValues[5] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale5->text().toDouble(); transformValues[6] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale6->text().toDouble(); transformValues[7] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->text().toDouble(); transformValues[8] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->text().toDouble(); transformValues[9] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->text().toDouble(); transformValues[10] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->text().toDouble(); transformValues[11] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->text().toDouble(); transformValues[12] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->text().toDouble(); transformValues[13] = m_Controls.m_CenterForInitializerFixedCenterOfRotationAffine->isChecked(); transformValues[14] = m_Controls.m_MomentsFixedCenterOfRotationAffine->isChecked(); return transformValues; } void QmitkFixedCenterOfRotationAffineTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesFixedCenterOfRotationAffine->setChecked(transformValues[0]); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale4->setText(QString::number(transformValues[4])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale5->setText(QString::number(transformValues[5])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale6->setText(QString::number(transformValues[6])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->setText(QString::number(transformValues[7])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->setText(QString::number(transformValues[8])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->setText(QString::number(transformValues[9])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->setText(QString::number(transformValues[10])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->setText(QString::number(transformValues[11])); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->setText(QString::number(transformValues[12])); m_Controls.m_CenterForInitializerFixedCenterOfRotationAffine->setChecked(transformValues[13]); m_Controls.m_MomentsFixedCenterOfRotationAffine->setChecked(transformValues[14]); m_Controls.m_GeometryFixedCenterOfRotationAffine->setChecked(!transformValues[14]); } QString QmitkFixedCenterOfRotationAffineTransformView::GetName() { return "FixedCenterOfRotationAffine"; } void QmitkFixedCenterOfRotationAffineTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale4->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale5->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale6->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); } itk::Array QmitkFixedCenterOfRotationAffineTransformView::GetScales() { itk::Array scales; scales.SetSize(12); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesFixedCenterOfRotationAffine->isChecked()) { scales[0] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale4->text().toDouble(); scales[4] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale5->text().toDouble(); scales[5] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale6->text().toDouble(); scales[6] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->text().toDouble(); scales[7] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->text().toDouble(); scales[8] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->text().toDouble(); scales[9] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->text().toDouble(); scales[10] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->text().toDouble(); scales[11] = m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->text().toDouble(); } return scales; } vtkTransform* QmitkFixedCenterOfRotationAffineTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { int m = 0; for (unsigned int i = 0; i < m_FixedImage->GetDimension(); i++) { for (unsigned int j = 0; j < m_FixedImage->GetDimension(); j++) { vtkmatrix->SetElement(i, j, transformParams[m]); m++; } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); if (m_FixedImage->GetDimension() == 2) { vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[4]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[5]); } else if (m_FixedImage->GetDimension() == 3) { vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[9]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[10]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[11]); } vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkFixedCenterOfRotationAffineTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) { m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->hide(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->hide(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->hide(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->hide(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->hide(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->hide(); m_Controls.textLabel2_7_2_2->setText("Translation Scale X:"); m_Controls.textLabel3_6_2_2->setText("Translation Scale Y:"); m_Controls.textLabel4_4_3_2->hide(); m_Controls.textLabel5_4_2_2->hide(); m_Controls.textLabel6_4_2_2->hide(); m_Controls.textLabel11_3_2_2->hide(); m_Controls.textLabel12_3_2_2->hide(); m_Controls.textLabel13_2_2_2->hide(); return 6; } else { m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale7->show(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale8->show(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScale9->show(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationX->show(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationY->show(); m_Controls.m_ScalesFixedCenterOfRotationAffineTransformScaleTranslationZ->show(); m_Controls.textLabel2_7_2_2->setText("Scale 5:"); m_Controls.textLabel3_6_2_2->setText("Scale 6:"); m_Controls.textLabel4_4_3_2->show(); m_Controls.textLabel5_4_2_2->show(); m_Controls.textLabel6_4_2_2->show(); m_Controls.textLabel11_3_2_2->show(); m_Controls.textLabel12_3_2_2->show(); m_Controls.textLabel13_2_2_2->show(); return 12; } } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkQuaternionRigidTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkQuaternionRigidTransformView.cpp index 89b956eb19..3f559a5724 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkQuaternionRigidTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkQuaternionRigidTransformView.cpp @@ -1,197 +1,203 @@ /*=================================================================== 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 "QmitkQuaternionRigidTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkQuaternionRigidTransformView::QmitkQuaternionRigidTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkQuaternionRigidTransformView::~QmitkQuaternionRigidTransformView() { } mitk::TransformParameters::TransformType QmitkQuaternionRigidTransformView::GetTransformType() { return mitk::TransformParameters::QUATERNIONRIGIDTRANSFORM; } itk::Object::Pointer QmitkQuaternionRigidTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 3); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkQuaternionRigidTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkQuaternionRigidTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 3) { - typedef typename itk::Image< TPixelType, 3 > FixedImage3DType; - typedef typename itk::Image< TPixelType, 3 > MovingImage3DType; - typename FixedImage3DType::Pointer fixedImage3D; - mitk::CastToItkImage(m_FixedImage, fixedImage3D); - typename MovingImage3DType::Pointer movingImage3D; - mitk::CastToItkImage(m_MovingImage, movingImage3D); + typedef typename itk::Image< TPixelType, 3 > FixedImageType; + typedef typename itk::Image< TPixelType, 3 > MovingImageType; + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImageType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImageType::Pointer movingImage = movingImageToItk->GetOutput(); + typename itk::QuaternionRigidTransform< double >::Pointer transformPointer = itk::QuaternionRigidTransform< double >::New(); transformPointer->SetIdentity(); typedef typename itk::QuaternionRigidTransform< double > QuaternionRigidTransformType; if (m_Controls.m_CenterForInitializerQuaternionRigid->isChecked()) { - typedef typename itk::CenteredTransformInitializer TransformInitializerType; + typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); - transformInitializer->SetFixedImage( fixedImage3D ); - transformInitializer->SetMovingImage( movingImage3D ); + transformInitializer->SetFixedImage( fixedImage ); + transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsQuaternionRigid->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkQuaternionRigidTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(10); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesQuaternionRigid->isChecked(); transformValues[1] = m_Controls.m_ScalesQuaternionRigidTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesQuaternionRigidTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesQuaternionRigidTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesQuaternionRigidTransformScale4->text().toDouble(); transformValues[5] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationX->text().toDouble(); transformValues[6] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationY->text().toDouble(); transformValues[7] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationZ->text().toDouble(); transformValues[8] = m_Controls.m_CenterForInitializerQuaternionRigid->isChecked(); transformValues[9] = m_Controls.m_MomentsQuaternionRigid->isChecked(); return transformValues; } void QmitkQuaternionRigidTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesQuaternionRigid->setChecked(transformValues[0]); m_Controls.m_ScalesQuaternionRigidTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesQuaternionRigidTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesQuaternionRigidTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesQuaternionRigidTransformScale4->setText(QString::number(transformValues[4])); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationX->setText(QString::number(transformValues[5])); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationY->setText(QString::number(transformValues[6])); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationZ->setText(QString::number(transformValues[7])); m_Controls.m_CenterForInitializerQuaternionRigid->setChecked(transformValues[8]); m_Controls.m_MomentsQuaternionRigid->setChecked(transformValues[9]); m_Controls.m_GeometryQuaternionRigid->setChecked(!transformValues[9]); } QString QmitkQuaternionRigidTransformView::GetName() { return "QuaternionRigid"; } void QmitkQuaternionRigidTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesQuaternionRigidTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScale4->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); } itk::Array QmitkQuaternionRigidTransformView::GetScales() { itk::Array scales; scales.SetSize(7); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesQuaternionRigid->isChecked()) { scales[0] = m_Controls.m_ScalesQuaternionRigidTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesQuaternionRigidTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesQuaternionRigidTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesQuaternionRigidTransformScale4->text().toDouble(); scales[4] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationX->text().toDouble(); scales[5] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationY->text().toDouble(); scales[6] = m_Controls.m_ScalesQuaternionRigidTransformScaleTranslationZ->text().toDouble(); } return scales; } vtkTransform* QmitkQuaternionRigidTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { itk::QuaternionRigidTransform::Pointer quaternionTransform = itk::QuaternionRigidTransform::New(); quaternionTransform->SetParameters(transformParams); itk::Matrix Matrix = quaternionTransform->GetMatrix(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { vtkmatrix->SetElement(i, j, Matrix[i][j]); } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[4]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[5]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[6]); vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkQuaternionRigidTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 0; else return 7; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkRigid2DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkRigid2DTransformView.cpp index df5eaf94f5..a2500abc83 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkRigid2DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkRigid2DTransformView.cpp @@ -1,162 +1,169 @@ /*=================================================================== 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 "QmitkRigid2DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkRigid2DTransformView::QmitkRigid2DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkRigid2DTransformView::~QmitkRigid2DTransformView() { } mitk::TransformParameters::TransformType QmitkRigid2DTransformView::GetTransformType() { return mitk::TransformParameters::RIGID2DTRANSFORM; } itk::Object::Pointer QmitkRigid2DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkRigid2DTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkRigid2DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 2) { typedef typename itk::Image< TPixelType, 2 > FixedImage2DType; typedef typename itk::Image< TPixelType, 2 > MovingImage2DType; - typename FixedImage2DType::Pointer fixedImage2D; - mitk::CastToItkImage(m_FixedImage, fixedImage2D); - typename MovingImage2DType::Pointer movingImage2D; - mitk::CastToItkImage(m_MovingImage, movingImage2D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage2DType::Pointer fixedImage2D = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = + mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage2DType::Pointer movingImage2D = movingImageToItk->GetOutput(); + typename itk::Rigid2DTransform< double >::Pointer transformPointer = itk::Rigid2DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerRigid2D->isChecked()) { typedef typename itk::Rigid2DTransform< double > Rigid2DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage2D ); transformInitializer->SetMovingImage( movingImage2D ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsRigid2D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkRigid2DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(6); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesRigid2D->isChecked(); transformValues[1] = m_Controls.m_ScalesRigid2DTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesRigid2DTransformScaleTranslationX->text().toDouble(); transformValues[3] = m_Controls.m_ScalesRigid2DTransformScaleTranslationY->text().toDouble(); transformValues[4] = m_Controls.m_CenterForInitializerRigid2D->isChecked(); transformValues[5] = m_Controls.m_MomentsRigid2D->isChecked(); return transformValues; } void QmitkRigid2DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesRigid2D->setChecked(transformValues[0]); m_Controls.m_ScalesRigid2DTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesRigid2DTransformScaleTranslationX->setText(QString::number(transformValues[2])); m_Controls.m_ScalesRigid2DTransformScaleTranslationY->setText(QString::number(transformValues[3])); m_Controls.m_CenterForInitializerRigid2D->setChecked(transformValues[4]); m_Controls.m_MomentsRigid2D->setChecked(transformValues[5]); m_Controls.m_GeometryRigid2D->setChecked(!transformValues[5]); } QString QmitkRigid2DTransformView::GetName() { return "Rigid2D"; } void QmitkRigid2DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesRigid2DTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesRigid2DTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesRigid2DTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); } itk::Array QmitkRigid2DTransformView::GetScales() { itk::Array scales; scales.SetSize(3); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesRigid2D->isChecked()) { scales[0] = m_Controls.m_ScalesRigid2DTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesRigid2DTransformScaleTranslationX->text().toDouble(); scales[2] = m_Controls.m_ScalesRigid2DTransformScaleTranslationY->text().toDouble(); } return scales; } vtkTransform* QmitkRigid2DTransformView::Transform(vtkMatrix4x4* /*vtkmatrix*/, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { mitk::ScalarType angle = transformParams[0] * 45.0 / atan(1.0); vtktransform->PostMultiply(); vtktransform->RotateZ(angle); vtktransform->Translate(transformParams[1], transformParams[2], 0); vtktransform->PreMultiply(); } return vtktransform; } int QmitkRigid2DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 3; else return 0; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkScaleSkewVersor3DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkScaleSkewVersor3DTransformView.cpp index 0789d591bb..5c7fd29278 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkScaleSkewVersor3DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkScaleSkewVersor3DTransformView.cpp @@ -1,228 +1,235 @@ /*=================================================================== 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 "QmitkScaleSkewVersor3DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkScaleSkewVersor3DTransformView::QmitkScaleSkewVersor3DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkScaleSkewVersor3DTransformView::~QmitkScaleSkewVersor3DTransformView() { } mitk::TransformParameters::TransformType QmitkScaleSkewVersor3DTransformView::GetTransformType() { return mitk::TransformParameters::SCALESKEWVERSOR3DTRANSFORM; } itk::Object::Pointer QmitkScaleSkewVersor3DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 3); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkScaleSkewVersor3DTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkScaleSkewVersor3DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 3) { - typedef typename itk::Image< TPixelType, 3 > FixedImage3DType; - typedef typename itk::Image< TPixelType, 3 > MovingImage3DType; - typename FixedImage3DType::Pointer fixedImage3D; - mitk::CastToItkImage(m_FixedImage, fixedImage3D); - typename MovingImage3DType::Pointer movingImage3D; - mitk::CastToItkImage(m_MovingImage, movingImage3D); + typedef typename itk::Image< TPixelType, 3 > FixedImageType; + typedef typename itk::Image< TPixelType, 3 > MovingImageType; + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImageType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImageType::Pointer movingImage = movingImageToItk->GetOutput(); + + typename itk::ScaleSkewVersor3DTransform< double >::Pointer transformPointer = itk::ScaleSkewVersor3DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerScaleSkewVersorRigid3D->isChecked()) { typedef typename itk::ScaleSkewVersor3DTransform< double > ScaleSkewVersor3DTransformType; - typedef typename itk::CenteredTransformInitializer TransformInitializerType; + typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); - transformInitializer->SetFixedImage( fixedImage3D ); - transformInitializer->SetMovingImage( movingImage3D ); + transformInitializer->SetFixedImage( fixedImage ); + transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsScaleSkewVersorRigid3D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkScaleSkewVersor3DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(18); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesScaleSkewVersorRigid3DTransform->isChecked(); transformValues[1] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationX->text().toDouble(); transformValues[5] = m_Controls.m_ScaleScaleSkewVersorRigid3DTransformScaleTranslationY->text().toDouble(); transformValues[6] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationZ->text().toDouble(); transformValues[7] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale7->text().toDouble(); transformValues[8] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale8->text().toDouble(); transformValues[9] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale9->text().toDouble(); transformValues[10] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale10->text().toDouble(); transformValues[11] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale11->text().toDouble(); transformValues[12] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale12->text().toDouble(); transformValues[13] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale13->text().toDouble(); transformValues[14] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale14->text().toDouble(); transformValues[15] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale15->text().toDouble(); transformValues[16] = m_Controls.m_CenterForInitializerScaleSkewVersorRigid3D->isChecked(); transformValues[17] = m_Controls.m_MomentsScaleSkewVersorRigid3D->isChecked(); return transformValues; } void QmitkScaleSkewVersor3DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesScaleSkewVersorRigid3DTransform->setChecked(transformValues[0]); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationX->setText(QString::number(transformValues[4])); m_Controls.m_ScaleScaleSkewVersorRigid3DTransformScaleTranslationY->setText(QString::number(transformValues[5])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationZ->setText(QString::number(transformValues[6])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale7->setText(QString::number(transformValues[7])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale8->setText(QString::number(transformValues[8])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale9->setText(QString::number(transformValues[9])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale10->setText(QString::number(transformValues[10])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale11->setText(QString::number(transformValues[11])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale12->setText(QString::number(transformValues[12])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale13->setText(QString::number(transformValues[13])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale14->setText(QString::number(transformValues[14])); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale15->setText(QString::number(transformValues[15])); m_Controls.m_CenterForInitializerScaleSkewVersorRigid3D->setChecked(transformValues[16]); m_Controls.m_MomentsScaleSkewVersorRigid3D->setChecked(transformValues[17]); m_Controls.m_GeometryScaleSkewVersorRigid3D->setChecked(!transformValues[17]); } QString QmitkScaleSkewVersor3DTransformView::GetName() { return "ScaleSkewVersor3D"; } void QmitkScaleSkewVersor3DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScaleScaleSkewVersorRigid3DTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale7->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale8->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale9->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale10->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale11->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale12->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale13->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale14->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale15->setValidator(validatorLineEditInputFloat); } itk::Array QmitkScaleSkewVersor3DTransformView::GetScales() { itk::Array scales; scales.SetSize(15); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesScaleSkewVersorRigid3DTransform->isChecked()) { scales[0] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationX->text().toDouble(); scales[4] = m_Controls.m_ScaleScaleSkewVersorRigid3DTransformScaleTranslationY->text().toDouble(); scales[5] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScaleTranslationZ->text().toDouble(); scales[6] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale7->text().toDouble(); scales[7] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale8->text().toDouble(); scales[8] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale9->text().toDouble(); scales[9] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale10->text().toDouble(); scales[10] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale11->text().toDouble(); scales[11] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale12->text().toDouble(); scales[12] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale13->text().toDouble(); scales[13] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale14->text().toDouble(); scales[14] = m_Controls.m_ScalesScaleSkewVersorRigid3DTransformScale15->text().toDouble(); } return scales; } vtkTransform* QmitkScaleSkewVersor3DTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { itk::ScaleSkewVersor3DTransform::Pointer versorTransform = itk::ScaleSkewVersor3DTransform::New(); versorTransform->SetParameters(transformParams); itk::Matrix Matrix = versorTransform->GetMatrix(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { vtkmatrix->SetElement(i, j, Matrix[i][j]); } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[3]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[4]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[5]); vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkScaleSkewVersor3DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 0; else return 15; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity2DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity2DTransformView.cpp index 1d0d6335fb..a303046921 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity2DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity2DTransformView.cpp @@ -1,173 +1,181 @@ /*=================================================================== 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 "QmitkSimilarity2DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkSimilarity2DTransformView::QmitkSimilarity2DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkSimilarity2DTransformView::~QmitkSimilarity2DTransformView() { } mitk::TransformParameters::TransformType QmitkSimilarity2DTransformView::GetTransformType() { return mitk::TransformParameters::SIMILARITY2DTRANSFORM; } itk::Object::Pointer QmitkSimilarity2DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 2); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkSimilarity2DTransformView::GetTransform2(itk::Image* /* itkImage1 */) +itk::Object::Pointer QmitkSimilarity2DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 2) { typedef typename itk::Image< TPixelType, 2 > FixedImage2DType; typedef typename itk::Image< TPixelType, 2 > MovingImage2DType; - typename FixedImage2DType::Pointer fixedImage2D; - mitk::CastToItkImage(m_FixedImage, fixedImage2D); - typename MovingImage2DType::Pointer movingImage2D; - mitk::CastToItkImage(m_MovingImage, movingImage2D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage2DType::Pointer fixedImage2D = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = + mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage2DType::Pointer movingImage2D = movingImageToItk->GetOutput(); + + typename itk::Similarity2DTransform< double >::Pointer transformPointer = itk::Similarity2DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerSimilarity2D->isChecked()) { typedef typename itk::Similarity2DTransform< double > Similarity2DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); transformInitializer->SetFixedImage( fixedImage2D ); transformInitializer->SetMovingImage( movingImage2D ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsSimilarity2D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } transformPointer->SetScale( m_Controls.m_InitialScaleSimilarity2D->text().toFloat() ); transformPointer->SetAngle( m_Controls.m_AngleSimilarity2D->text().toFloat() ); m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkSimilarity2DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(9); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesSimilarity2D->isChecked(); transformValues[1] = m_Controls.m_ScalingScaleSimilarity2D->text().toDouble(); transformValues[2] = m_Controls.m_RotationScaleSimilarity2D->text().toDouble(); transformValues[3] = m_Controls.m_TranslationXScaleSimilarity2D->text().toDouble(); transformValues[4] = m_Controls.m_TranslationYScaleSimilarity2D->text().toDouble(); transformValues[5] = m_Controls.m_InitialScaleSimilarity2D->text().toFloat(); transformValues[6] = m_Controls.m_AngleSimilarity2D->text().toFloat(); transformValues[7] = m_Controls.m_CenterForInitializerSimilarity2D->isChecked(); transformValues[8] = m_Controls.m_MomentsSimilarity2D->isChecked(); return transformValues; } void QmitkSimilarity2DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesSimilarity2D->setChecked(transformValues[0]); m_Controls.m_ScalingScaleSimilarity2D->setText(QString::number(transformValues[1])); m_Controls.m_RotationScaleSimilarity2D->setText(QString::number(transformValues[2])); m_Controls.m_TranslationXScaleSimilarity2D->setText(QString::number(transformValues[3])); m_Controls.m_TranslationYScaleSimilarity2D->setText(QString::number(transformValues[4])); m_Controls.m_InitialScaleSimilarity2D->setText(QString::number(transformValues[5])); m_Controls.m_AngleSimilarity2D->setText(QString::number(transformValues[6])); m_Controls.m_CenterForInitializerSimilarity2D->setChecked(transformValues[7]); m_Controls.m_MomentsSimilarity2D->setChecked(transformValues[8]); m_Controls.m_GeometrySimilarity2D->setChecked(!transformValues[8]); } QString QmitkSimilarity2DTransformView::GetName() { return "Similarity2D"; } void QmitkSimilarity2DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalingScaleSimilarity2D->setValidator(validatorLineEditInputFloat); m_Controls.m_RotationScaleSimilarity2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationXScaleSimilarity2D->setValidator(validatorLineEditInputFloat); m_Controls.m_TranslationYScaleSimilarity2D->setValidator(validatorLineEditInputFloat); } itk::Array QmitkSimilarity2DTransformView::GetScales() { itk::Array scales; scales.SetSize(4); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesSimilarity2D->isChecked()) { scales[0] = m_Controls.m_ScalingScaleSimilarity2D->text().toDouble(); scales[1] = m_Controls.m_RotationScaleSimilarity2D->text().toDouble(); scales[2] = m_Controls.m_TranslationXScaleSimilarity2D->text().toDouble(); scales[3] = m_Controls.m_TranslationYScaleSimilarity2D->text().toDouble(); } return scales; } vtkTransform* QmitkSimilarity2DTransformView::Transform(vtkMatrix4x4* /* vtkmatrix */, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { mitk::ScalarType angle = transformParams[1] * 45.0 / atan(1.0); vtktransform->PostMultiply(); vtktransform->Scale(transformParams[0], transformParams[0], 1); vtktransform->RotateZ(angle); vtktransform->Translate(transformParams[2], transformParams[3], 0); vtktransform->PreMultiply(); } return vtktransform; } int QmitkSimilarity2DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 4; else return 0; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity3DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity3DTransformView.cpp index bbea4b71a4..376643a3b6 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity3DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkSimilarity3DTransformView.cpp @@ -1,197 +1,203 @@ /*=================================================================== 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 "QmitkSimilarity3DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkSimilarity3DTransformView::QmitkSimilarity3DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkSimilarity3DTransformView::~QmitkSimilarity3DTransformView() { } mitk::TransformParameters::TransformType QmitkSimilarity3DTransformView::GetTransformType() { return mitk::TransformParameters::SIMILARITY3DTRANSFORM; } itk::Object::Pointer QmitkSimilarity3DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 3); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkSimilarity3DTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkSimilarity3DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 3) { typedef typename itk::Image< TPixelType, 3 > FixedImage3DType; typedef typename itk::Image< TPixelType, 3 > MovingImage3DType; - typename FixedImage3DType::Pointer fixedImage3D; - mitk::CastToItkImage(m_FixedImage, fixedImage3D); - typename MovingImage3DType::Pointer movingImage3D; - mitk::CastToItkImage(m_MovingImage, movingImage3D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage3DType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage3DType::Pointer movingImage = movingImageToItk->GetOutput(); + typename itk::Similarity3DTransform< double >::Pointer transformPointer = itk::Similarity3DTransform< double >::New(); transformPointer->SetIdentity(); if (m_Controls.m_CenterForInitializerSimilarity3D->isChecked()) { typedef typename itk::Similarity3DTransform< double > Similarity3DTransformType; typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); - transformInitializer->SetFixedImage( fixedImage3D ); - transformInitializer->SetMovingImage( movingImage3D ); + transformInitializer->SetFixedImage( fixedImage ); + transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsSimilarity3D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkSimilarity3DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(10); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesSimilarity3D->isChecked(); transformValues[1] = m_Controls.m_ScalesSimilarity3DTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesSimilarity3DTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesSimilarity3DTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesSimilarity3DTransformScale4->text().toDouble(); transformValues[5] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationX->text().toDouble(); transformValues[6] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationY->text().toDouble(); transformValues[7] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationZ->text().toDouble(); transformValues[8] = m_Controls.m_CenterForInitializerSimilarity3D->isChecked(); transformValues[9] = m_Controls.m_MomentsSimilarity3D->isChecked(); return transformValues; } void QmitkSimilarity3DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesSimilarity3D->setChecked(transformValues[0]); m_Controls.m_ScalesSimilarity3DTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesSimilarity3DTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesSimilarity3DTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesSimilarity3DTransformScale4->setText(QString::number(transformValues[4])); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationX->setText(QString::number(transformValues[5])); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationY->setText(QString::number(transformValues[6])); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationZ->setText(QString::number(transformValues[7])); m_Controls.m_CenterForInitializerSimilarity3D->setChecked(transformValues[8]); m_Controls.m_MomentsSimilarity3D->setChecked(transformValues[9]); m_Controls.m_GeometrySimilarity3D->setChecked(!transformValues[9]); } QString QmitkSimilarity3DTransformView::GetName() { return "Similarity3D"; } void QmitkSimilarity3DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesSimilarity3DTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScale4->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesSimilarity3DTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); } itk::Array QmitkSimilarity3DTransformView::GetScales() { itk::Array scales; scales.SetSize(7); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesSimilarity3D->isChecked()) { scales[0] = m_Controls.m_ScalesSimilarity3DTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesSimilarity3DTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesSimilarity3DTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesSimilarity3DTransformScale4->text().toDouble(); scales[4] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationX->text().toDouble(); scales[5] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationY->text().toDouble(); scales[6] = m_Controls.m_ScalesSimilarity3DTransformScaleTranslationZ->text().toDouble(); } return scales; } vtkTransform* QmitkSimilarity3DTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { itk::Similarity3DTransform::Pointer similarityTransform = itk::Similarity3DTransform::New(); similarityTransform->SetParameters(transformParams); itk::Matrix Matrix = similarityTransform->GetMatrix(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { vtkmatrix->SetElement(i, j, Matrix[i][j]); } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[4]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[5]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[6]); vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkSimilarity3DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 0; else return 7; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorRigid3DTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorRigid3DTransformView.cpp index 10bb83975a..2a4fed2e8d 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorRigid3DTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorRigid3DTransformView.cpp @@ -1,208 +1,214 @@ /*=================================================================== 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 "QmitkVersorRigid3DTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkVersorRigid3DTransformView::QmitkVersorRigid3DTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkVersorRigid3DTransformView::~QmitkVersorRigid3DTransformView() { } mitk::TransformParameters::TransformType QmitkVersorRigid3DTransformView::GetTransformType() { return mitk::TransformParameters::VERSORRIGID3DTRANSFORM; } itk::Object::Pointer QmitkVersorRigid3DTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 3); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkVersorRigid3DTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkVersorRigid3DTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 3) { typedef typename itk::Image< TPixelType, 3 > FixedImage3DType; typedef typename itk::Image< TPixelType, 3 > MovingImage3DType; - typename FixedImage3DType::Pointer fixedImage3D; - mitk::CastToItkImage(m_FixedImage, fixedImage3D); - typename MovingImage3DType::Pointer movingImage3D; - mitk::CastToItkImage(m_MovingImage, movingImage3D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage3DType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage3DType::Pointer movingImage = movingImageToItk->GetOutput(); + typename itk::VersorRigid3DTransform< double >::Pointer transformPointer = itk::VersorRigid3DTransform< double >::New(); transformPointer->SetIdentity(); typedef typename itk::VersorRigid3DTransform< double > VersorRigid3DTransformType; if (m_Controls.m_CenterForInitializerVersorRigid3D->isChecked()) { typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); - transformInitializer->SetFixedImage( fixedImage3D ); - transformInitializer->SetMovingImage( movingImage3D ); + transformInitializer->SetFixedImage( fixedImage ); + transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsVersorRigid3D->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } typedef VersorRigid3DTransformType::VersorType VersorType; typedef VersorType::VectorType VectorType; VersorType rotation; VectorType axis; axis[0] = 0.0; axis[1] = 0.0; axis[2] = 1.0; const double angle = 0; rotation.Set( axis, angle ); transformPointer->SetRotation( rotation ); m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkVersorRigid3DTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(9); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesVersorRigid3D->isChecked(); transformValues[1] = m_Controls.m_ScalesVersorRigid3DTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesVersorRigid3DTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesVersorRigid3DTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationX->text().toDouble(); transformValues[5] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationY->text().toDouble(); transformValues[6] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationZ->text().toDouble(); transformValues[7] = m_Controls.m_CenterForInitializerVersorRigid3D->isChecked(); transformValues[8] = m_Controls.m_MomentsVersorRigid3D->isChecked(); return transformValues; } void QmitkVersorRigid3DTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesVersorRigid3D->setChecked(transformValues[0]); m_Controls.m_ScalesVersorRigid3DTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesVersorRigid3DTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesVersorRigid3DTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationX->setText(QString::number(transformValues[4])); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationY->setText(QString::number(transformValues[5])); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationZ->setText(QString::number(transformValues[6])); m_Controls.m_CenterForInitializerVersorRigid3D->setChecked(transformValues[7]); m_Controls.m_MomentsVersorRigid3D->setChecked(transformValues[8]); m_Controls.m_GeometryVersorRigid3D->setChecked(!transformValues[8]); } QString QmitkVersorRigid3DTransformView::GetName() { return "VersorRigid3D"; } void QmitkVersorRigid3DTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesVersorRigid3DTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorRigid3DTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorRigid3DTransformScale3->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationX->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationY->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationZ->setValidator(validatorLineEditInputFloat); } itk::Array QmitkVersorRigid3DTransformView::GetScales() { itk::Array scales; scales.SetSize(6); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesVersorRigid3D->isChecked()) { scales[0] = m_Controls.m_ScalesVersorRigid3DTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesVersorRigid3DTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesVersorRigid3DTransformScale3->text().toDouble(); scales[3] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationX->text().toDouble(); scales[4] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationY->text().toDouble(); scales[5] = m_Controls.m_ScalesVersorRigid3DTransformScaleTranslationZ->text().toDouble(); } return scales; } vtkTransform* QmitkVersorRigid3DTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { itk::VersorRigid3DTransform::Pointer versorTransform = itk::VersorRigid3DTransform::New(); versorTransform->SetParameters(transformParams); itk::Matrix Matrix = versorTransform->GetMatrix(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { vtkmatrix->SetElement(i, j, Matrix[i][j]); } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); vtkmatrix->SetElement(0, 3, -translation[0] + center[0] + transformParams[3]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1] + transformParams[4]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2] + transformParams[5]); vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkVersorRigid3DTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 0; else return 6; } else return 0; } diff --git a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorTransformView.cpp b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorTransformView.cpp index 677de1cb58..7887289566 100644 --- a/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorTransformView.cpp +++ b/Modules/RigidRegistrationUI/RigidRegistrationTransforms/QmitkVersorTransformView.cpp @@ -1,181 +1,187 @@ /*=================================================================== 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 "QmitkVersorTransformView.h" #include "mitkImageAccessByItk.h" #include #include #include #include QmitkVersorTransformView::QmitkVersorTransformView(QWidget* parent, Qt::WindowFlags f ) : QmitkRigidRegistrationTransformsGUIBase(parent, f), m_CenterX(0), m_CenterY(0), m_CenterZ(0) { } QmitkVersorTransformView::~QmitkVersorTransformView() { } mitk::TransformParameters::TransformType QmitkVersorTransformView::GetTransformType() { return mitk::TransformParameters::VERSORTRANSFORM; } itk::Object::Pointer QmitkVersorTransformView::GetTransform() { if (m_FixedImage.IsNotNull()) { - AccessByItk(m_FixedImage, GetTransform2); + AccessFixedDimensionByItk(m_FixedImage, GetTransform2, 3); return m_TransformObject; } return NULL; } template < class TPixelType, unsigned int VImageDimension > -itk::Object::Pointer QmitkVersorTransformView::GetTransform2(itk::Image* /*itkImage1*/) +itk::Object::Pointer QmitkVersorTransformView::GetTransform2(itk::Image* itkImage1) { if (VImageDimension == 3) { typedef typename itk::Image< TPixelType, 3 > FixedImage3DType; typedef typename itk::Image< TPixelType, 3 > MovingImage3DType; - typename FixedImage3DType::Pointer fixedImage3D; - mitk::CastToItkImage(m_FixedImage, fixedImage3D); - typename MovingImage3DType::Pointer movingImage3D; - mitk::CastToItkImage(m_MovingImage, movingImage3D); + + // the fixedImage is the input parameter (fix for Bug #14626) + typename FixedImage3DType::Pointer fixedImage = itkImage1; + + // the movingImage type is known, use the ImageToItk filter (fix for Bug #14626) + typename mitk::ImageToItk::Pointer movingImageToItk = mitk::ImageToItk::New(); + movingImageToItk->SetInput(m_MovingImage); + movingImageToItk->Update(); + typename MovingImage3DType::Pointer movingImage = movingImageToItk->GetOutput(); + typename itk::VersorTransform< double >::Pointer transformPointer = itk::VersorTransform< double >::New(); transformPointer->SetIdentity(); typedef typename itk::VersorTransform< double > VersorTransformType; if (m_Controls.m_CenterForInitializerVersor->isChecked()) { typedef typename itk::CenteredTransformInitializer TransformInitializerType; typename TransformInitializerType::Pointer transformInitializer = TransformInitializerType::New(); - transformInitializer->SetFixedImage( fixedImage3D ); - transformInitializer->SetMovingImage( movingImage3D ); + transformInitializer->SetFixedImage( fixedImage ); + transformInitializer->SetMovingImage( movingImage ); transformInitializer->SetTransform( transformPointer ); if (m_Controls.m_MomentsVersor->isChecked()) { transformInitializer->MomentsOn(); } else { transformInitializer->GeometryOn(); } transformInitializer->InitializeTransform(); } m_CenterX = transformPointer->GetCenter()[0]; m_CenterY = transformPointer->GetCenter()[1]; m_CenterZ = transformPointer->GetCenter()[2]; m_TransformObject = transformPointer.GetPointer(); return transformPointer.GetPointer(); } return NULL; } itk::Array QmitkVersorTransformView::GetTransformParameters() { itk::Array transformValues; transformValues.SetSize(6); transformValues.fill(0); transformValues[0] = m_Controls.m_UseOptimizerScalesVersor->isChecked(); transformValues[1] = m_Controls.m_ScalesVersorTransformScale1->text().toDouble(); transformValues[2] = m_Controls.m_ScalesVersorTransformScale2->text().toDouble(); transformValues[3] = m_Controls.m_ScalesVersorTransformScale3->text().toDouble(); transformValues[4] = m_Controls.m_CenterForInitializerVersor->isChecked(); transformValues[5] = m_Controls.m_MomentsVersor->isChecked(); return transformValues; } void QmitkVersorTransformView::SetTransformParameters(itk::Array transformValues) { m_Controls.m_UseOptimizerScalesVersor->setChecked(transformValues[0]); m_Controls.m_ScalesVersorTransformScale1->setText(QString::number(transformValues[1])); m_Controls.m_ScalesVersorTransformScale2->setText(QString::number(transformValues[2])); m_Controls.m_ScalesVersorTransformScale3->setText(QString::number(transformValues[3])); m_Controls.m_CenterForInitializerVersor->setChecked(transformValues[4]); m_Controls.m_MomentsVersor->setChecked(transformValues[5]); m_Controls.m_GeometryVersor->setChecked(!transformValues[5]); } QString QmitkVersorTransformView::GetName() { return "Versor"; } void QmitkVersorTransformView::SetupUI(QWidget* parent) { m_Controls.setupUi(parent); QValidator* validatorLineEditInputFloat = new QDoubleValidator(0, 20000000, 8, this); m_Controls.m_ScalesVersorTransformScale1->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorTransformScale2->setValidator(validatorLineEditInputFloat); m_Controls.m_ScalesVersorTransformScale3->setValidator(validatorLineEditInputFloat); } itk::Array QmitkVersorTransformView::GetScales() { itk::Array scales; scales.SetSize(3); scales.Fill(1.0); if (m_Controls.m_UseOptimizerScalesVersor->isChecked()) { scales[0] = m_Controls.m_ScalesVersorTransformScale1->text().toDouble(); scales[1] = m_Controls.m_ScalesVersorTransformScale2->text().toDouble(); scales[2] = m_Controls.m_ScalesVersorTransformScale3->text().toDouble(); } return scales; } vtkTransform* QmitkVersorTransformView::Transform(vtkMatrix4x4* vtkmatrix, vtkTransform* vtktransform, itk::Array transformParams) { if (m_MovingImage.IsNotNull()) { itk::VersorTransform::Pointer versorTransform = itk::VersorTransform::New(); versorTransform->SetParameters(transformParams); itk::Matrix Matrix = versorTransform->GetMatrix(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { vtkmatrix->SetElement(i, j, Matrix[i][j]); } } float center[4]; float translation[4]; center[0] = m_CenterX; center[1] = m_CenterY; center[2] = m_CenterZ; center[3] = 1; vtkmatrix->MultiplyPoint(center, translation); vtkmatrix->SetElement(0, 3, -translation[0] + center[0]); vtkmatrix->SetElement(1, 3, -translation[1] + center[1]); vtkmatrix->SetElement(2, 3, -translation[2] + center[2]); vtktransform->SetMatrix(vtkmatrix); } return vtktransform; } int QmitkVersorTransformView::GetNumberOfTransformParameters() { if (m_FixedImage.IsNotNull()) { if (m_FixedImage->GetDimension() == 2) return 0; else return 3; } else return 0; } diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.cmdlinemodules/documentation/UserManual/Manual.dox index fdb68854bd..c9781ecd5f 100644 --- a/Plugins/org.mitk.gui.qt.cmdlinemodules/documentation/UserManual/Manual.dox +++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/documentation/UserManual/Manual.dox @@ -1,175 +1,175 @@ /** -\bundlemainpage{org.mitk.gui.qt.cmdlinemodules} The Command Line Modules View +\page org_mitk_views_cmdlinemodules The Command Line Modules View \image html CLIIcon.png "Icon of the Command Line Modules View" \li \ref CLIIntroduction \li \ref CLIPreferences \li \ref CLIUsage \li \ref CLITechnicalNotes \section CLIPrefix Contribution This plugin was developed at the Centre For Medical Image Computing (CMIC), part of University College London (UCL) and contributed back to the MITK community with thanks. \section CLIIntroduction Introduction This view provides the facility to run third party command line programs, and load the data back into the DataManager for immediate visualisation. All that is required is that the command line application can be called with an argument of --xml and respond with a valid XML description of the necessary parameters, and currently, that if the program requires images, they must be NifTI images. This view can then generate a Graphical User Interface (GUI) dynamically from the XML to enable the user to interact with the command line application. This provides an easy to use, and potentially very flexible way to integrate almost any third party, medical imaging, command line application. As a high level introduction, this view performs the following steps: \li The view searches for available programs to run, and for each valid module, stores the XML document describing the interface, and populates a searchable list of available programs. \li When a program is selected, the GUI is generated. \li The user can then set the necessary parameters and run the program. \li Multiple programs can be launched in succession and run simultaneously, and where available on the host platform, the user can pause, resume or cancel running jobs and see console output for each job. As a consequence of the very flexible nature of this plugin, these instructions can only describe how to launch command line modules in a general sense. The examples shown have been constructed by downloading the latest version (subversion commit 329) of the NiftyReg package, available here, and described further here. NiftyReg provides valid XML descriptors to enable the integration of the NiftyReg affine (RegAladin) and and non-rigid (RegF3D) image registration algorithms, as well as utility programs to resample an image, and calculate a Jacobian image. These same XML descriptors work within Slicer and MITK based applications. \section CLIPreferences Preferences The first time that the Command Line Modules View is launched, it is advisable to set the user preferences for the view. Please refer to Figure 1. \image html CLIPreferences.png "Figure 1. The Command Line Modules Preferences Page" Each of these preferences is now explained in some detail. \li show debug output: If checked will output more messages to the console for debugging purposes. \li XML validation mode: The user may select a different mode for XML validation. If this is changed, the application will need to be restarted. There are 3 modes available. If the user selects "strict" mode, the XML schema produced by the command line application must exactly conform to this definition. For "none", there will be no validation. For "weak" validation, the application will report errors, but try to carry on and load as many modules as possible. The XML validation errors are available as tool-tips on the tab widget when the module is launched. Many third party modules included with Slicer currently have incorrect XML (typically, mis-ordered XML tags), and so the "weak" or "none" mode may assist in loading them. By default the "strict" mode is chosen so that only valid modules are loaded. \li max concurrent processes: Sets the maximum number of concurrent jobs that can be run via this interface. The default is 4. When the maximum number is reached, the green "Run" button is disabled until a job finishes. The next 7 preferences are to control where the view will search for valid command line programs. By default these are off as the searching process can take a long time and slow down the startup time of the GUI. The options provided are: \li scan home directory: Scan the users home directory. (See QDir::homePath().) \li scan home directory/cli-modules: Scans the sub-directory called cli-modules under the users home directory. \li scan current directory: Scan the current working directory. (See QDir::homePath().) \li scan current directory/cli-modules: Scans the sub-directory called cli-modules under the current working directory. \li scan installation directory: This is the directory where the actual application is stored. \li scan installation directory/cli-modules: Scans the sub-directory called cli-modules under the application installation directory. \li scan CTK_MODULE_LOAD_PATH: Scans the directory or list of directories defined by the environment variable CTK_MODULE_LOAD_PATH. A list is colon separated on Linux/Mac, and semi-colon separated on Windows. In most cases, it is suggested that the user will leave these options unchecked, as the user can also specify custom directories, and even cherry-pick specific command line programs to load. Figure 2 shows a selection box that enables the user to specify custom directories to scan, and Figure 3. shows a selection box that enables the user to select specific modules. Picking specific directories, and specific executables will most likely make the application quicker to launch. \image html CLIPreferencesAdditionalDirectories.png "Figure 2. The User can specify specific directories to scan". \image html CLIPreferencesAdditionalModules.png "Figure 3. The User can specify specific command line programs to load". These directory and file selection boxes enable directories or files to be added, removed and updated in a similar fashion. The user must make sure that the list of files selected in the "additional modules" section are not already contained within the directories specified in the "additional module directories" section. In addition, the preferences page provides: \li temporary directory: Images stored in the DataManager are first written to a temporary folder as Nifti images before being passed to each command line program. This temporary directory will default to a platform specific temporary folder, but the user may select their preferred choice of temporary workspace. \section CLIUsage Usage When the view is launched, a simple interface is presented, as shown in Figure 4. \image html CLIInitial.png "Figure 4. The initial interface, with no command line programs available." In this example, all the above check-box preferences were off, and the "additional module directories" was empty, and the "additional modules" list was empty so no command line applications were found. The "Search" box displays zero entries, and there is nothing to search. If the available search paths contain programs that are compatible (i.e. runnable) with this view, the name of the programs are displayed in the "Search" box in a nested menu, shown in Figure 5. \image html CLIWithPrograms.png "Figure 5. When valid paths are set, and programs are discovered, the menu is recalculated to show available programs." When a program is selected, the relevant interface is displayed, by default as collapsed group boxes to save space. Each section can be individually expanded if necessary to see the parameters. \image html CLINiftyReg.png "Figure 6. An example program, showing parameters for NiftyReg's program RegAladin." In this example, the parameters are displayed for NiftyReg produced at UCL, and more specifically for the affine registration program called RegAladin. The interface can contain a wide variety of controls. If a parameter for a command line program is an input image, then the widget displayed is linked to the DataManager, so that as new images are loaded, the correct image can be easily selected from the combo box. At this stage, multiple tabs can be opened, with one tab for each command line program. Figure 7 shows 2 tabs, for the RegAladin and RegF3D programs. \image html CLIF3D.png "Figure 7. Multiple tabs can be opened, one for each command line program." The main view provides some simple controls: \li Green arrow: Launch (run) the command line executable of the currently selected tab. \li Yellow undo arrow: Resets the GUI controls of the currently selected tab to default values, if and only if the original XML specified a default value. At this stage, nothing has been launched. When the user hits the green arrow button, a job is launched. Each running job is shown as a new progress reporting widget under the main tabbed widget, as shown in Figure 8. \image html CLINiftyRegRunning2.png "Figure 8. Multiple programs can be run, each with individual controls and console output." The controls for each running job are: \li Blue pause button: If supported on the host platform, this button will be enabled and can be toggled off (pause) or on (resume). \li Red square: If supported on the host platform, this button will kill the command line program. \li Black cross: Will remove the progress reporting widget from the GUI. When the user hits the green arrow in the main view: \li The currently selected tab is designated the "current" job, and contains the "current" set of parameters. \li A new progress reporting widget is created. \li The current parameters are copied to the progress reporting widget. In Figure 8. a parameters section is visible, and by default is collapsed, as they are simply for referring back to. \li All the output for the command line program is shown in the console widget, with a separate console for each job. \li Each new progress reporting widget is simply stacked vertically (newest is top-most), and it is up to the user to delete them when they are finished. It is easy to run multiple jobs. The green button simply launches the job corresponding to the current tab repeatedly. It is up to the user to make sure that any output file names are changed between successive invocations of the same command line module to avoid overwritting output data. In addition, each set of parameters contains an "About" section containing details of the contributors, the licence and acknowledgements and also a "Help" section containing a description and a link to any on-line documentation. These documentation features are provided by the developers of the third party plugin, and not by the host program. If information is missing, the user must contact the third party developers. \section CLITechnicalNotes Technical Notes From a technical perspective, the Command Line Modules View is a simple view, harnessing the power of the CTK command line modules framework. For technical information see: \li The doxygen generated manual page. \li The wiki page. and obviously the CTK code base. */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp index 79d18c1c8f..6ecdb77b95 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp @@ -1,815 +1,815 @@ /*=================================================================== 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 "QmitkIVIMView.h" #include "QmitkStdMultiWidget.h" // qt #include "qmessagebox.h" #include "qclipboard.h" // mitk #include "mitkDiffusionImage.h" #include "mitkImageCast.h" // itk #include "itkScalarImageToHistogramGenerator.h" #include "itkRegionOfInterestImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" // itk/mitk #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h" #include "itkRegularizedIVIMReconstructionFilter.h" #include "mitkImageCast.h" const std::string QmitkIVIMView::VIEW_ID = "org.mitk.views.ivim"; QmitkIVIMView::QmitkIVIMView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_Active(false) , m_SliceObserverTag1(0), m_SliceObserverTag2(0), m_SliceObserverTag3(0) , m_DiffusionImageNode(NULL) , m_MaskImageNode(NULL) { } QmitkIVIMView::~QmitkIVIMView() { // QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); // if(MultiWidget) // { // //unregister observers when view is destroyed // if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag1 ); // } // if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag2 ); // } // if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag3 ); // } // } } void QmitkIVIMView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkIVIMViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_ButtonStart, SIGNAL(clicked()), this, SLOT(FittIVIMStart()) ); connect( m_Controls->m_ButtonAutoThres, SIGNAL(clicked()), this, SLOT(AutoThreshold()) ); connect( m_Controls->m_MethodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(MethodCombo(int)) ); connect( m_Controls->m_DStarSlider, SIGNAL(valueChanged(int)), this, SLOT(DStarSlider(int)) ); connect( m_Controls->m_BThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(BThreshSlider(int)) ); connect( m_Controls->m_S0ThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(S0ThreshSlider(int)) ); connect( m_Controls->m_NumItSlider, SIGNAL(valueChanged(int)), this, SLOT(NumItsSlider(int)) ); connect( m_Controls->m_LambdaSlider, SIGNAL(valueChanged(int)), this, SLOT(LambdaSlider(int)) ); connect( m_Controls->m_CheckDStar, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_CheckD, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_Checkf, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_ChooseMethod, SIGNAL(clicked()), this, SLOT(ChooseMethod()) ); connect( m_Controls->m_CurveClipboard, SIGNAL(clicked()), this, SLOT(ClipboardCurveButtonClicked()) ); connect( m_Controls->m_ValuesClipboard, SIGNAL(clicked()), this, SLOT(ClipboardStatisticsButtonClicked()) ); } QString dstar = QString::number(m_Controls->m_DStarSlider->value()/1000.0); m_Controls->m_DStarLabel->setText(dstar); QString bthresh = QString::number(m_Controls->m_BThreshSlider->value()*5.0); m_Controls->m_BThreshLabel->setText(bthresh); QString s0thresh = QString::number(m_Controls->m_S0ThreshSlider->value()*0.5); m_Controls->m_S0ThreshLabel->setText(s0thresh); QString numits = QString::number(m_Controls->m_NumItSlider->value()); m_Controls->m_NumItsLabel->setText(numits); QString lambda = QString::number(m_Controls->m_LambdaSlider->value()*.00001); m_Controls->m_LambdaLabel->setText(lambda); m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); m_Controls->m_Warning->setVisible(false); MethodCombo(m_Controls->m_MethodCombo->currentIndex()); } void QmitkIVIMView::Checkbox() { itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::MethodCombo(int val) { switch(val) { case 0: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 1: m_Controls->m_DstarFrame->setVisible(true); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 2: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 3: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 4: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(false); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; } itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::DStarSlider (int val) { QString sval = QString::number(val/1000.0); m_Controls->m_DStarLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::BThreshSlider (int val) { QString sval = QString::number(val*5.0); m_Controls->m_BThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::S0ThreshSlider (int val) { QString sval = QString::number(val*0.5); m_Controls->m_S0ThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::NumItsSlider (int val) { QString sval = QString::number(val); m_Controls->m_NumItsLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::LambdaSlider (int val) { QString sval = QString::number(val*.00001); m_Controls->m_LambdaLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } } void QmitkIVIMView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkIVIMView::OnSelectionChanged( std::vector nodes ) { bool foundOneDiffusionImage = false; m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_MaskImageLabel->setText("optional"); m_MaskImageNode = NULL; m_DiffusionImageNode = NULL; // iterate all selected objects, adjust warning visibility for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast*>(node->GetData()) ) { m_DiffusionImageNode = node; foundOneDiffusionImage = true; m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_MaskImageNode = node; m_Controls->m_MaskImageLabel->setText(node->GetName().c_str()); } } } } if (m_DiffusionImageNode.IsNotNull()) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_InputData->setTitle("Input Data"); } else m_Controls->m_VisualizeResultsWidget->setVisible(false); m_Controls->m_ButtonStart->setEnabled( foundOneDiffusionImage ); m_Controls->m_ButtonAutoThres->setEnabled( foundOneDiffusionImage ); m_Controls->m_ControlsFrame->setEnabled( foundOneDiffusionImage ); m_Controls->m_BottomControlsFrame->setEnabled( foundOneDiffusionImage ); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::AutoThreshold() { std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing."); return; } typedef mitk::DiffusionImage DiffImgType; DiffImgType* dimg = dynamic_cast(nodes.front()->GetData()); if (!dimg) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } // find bzero index int index = -1; DiffImgType::GradientDirectionContainerType::Pointer directions = dimg->GetDirections(); for(DiffImgType::GradientDirectionContainerType::ConstIterator it = directions->Begin(); it != directions->End(); ++it) { index++; DiffImgType::GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = dimg->GetVectorImage(); int vecLength = vecimg->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; MITK_INFO << "Performing Histogram Analysis on Channel" << index; typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); mitk::CastToItkImage(dimg, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw = itw.Begin(); itk::ImageRegionConstIterator itr (vecimg, vecimg->GetLargestPossibleRegion() ); itr = itr.Begin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } typedef itk::Statistics::ScalarImageToHistogramGenerator< ImgType > HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); histogramGenerator->SetInput( img ); histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram histogramGenerator->SetNumberOfBins( 100 ); // CT range [-1024, +2048] --> bin size 4 values histogramGenerator->SetHistogramMin( dimg->GetScalarValueMin() ); histogramGenerator->SetHistogramMax( dimg->GetScalarValueMax() * .5 ); histogramGenerator->Compute(); HistogramType::ConstIterator iter = histogramGenerator->GetOutput()->Begin(); float maxFreq = 0; float maxValue = 0; while ( iter != histogramGenerator->GetOutput()->End() ) { if(iter.GetFrequency() > maxFreq) { maxFreq = iter.GetFrequency(); maxValue = iter.GetMeasurementVector()[0]; } ++iter; } maxValue *= 2; int sliderPos = maxValue * 2; m_Controls->m_S0ThreshSlider->setValue(sliderPos); S0ThreshSlider(sliderPos); } void QmitkIVIMView::FittIVIMStart() { std::vector nodes = this->GetDataManagerSelection(); - mitk::DiffusionImage* img; + mitk::DiffusionImage* img = 0; for ( int i=0; i*>(nodes.at(i)->GetData()); if (img) break; } if (!img) { QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = img->GetVectorImage(); OutImgType::IndexType dummy; FittIVIM(vecimg, img->GetDirections(), img->GetB_Value(), true, dummy); OutputToDatastorage(nodes); } void QmitkIVIMView::OnSliceChanged(const itk::EventObject& /*e*/) { if(!m_Visible) return; m_Controls->m_Warning->setVisible(false); if(!m_Controls || m_DiffusionImageNode.IsNull()) return; m_Controls->m_VisualizeResultsWidget->setVisible(false); mitk::DiffusionImage::Pointer diffusionImg = dynamic_cast*>(m_DiffusionImageNode->GetData()); mitk::Image::Pointer maskImg = NULL; if (m_MaskImageNode.IsNotNull()) maskImg = dynamic_cast(m_MaskImageNode->GetData()); if (!m_MultiWidget) return; typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = (VecImgType*)diffusionImg->GetVectorImage().GetPointer(); VecImgType::Pointer roiImage = VecImgType::New(); bool success = false; if(maskImg.IsNull()) { int roisize = 0; if(m_Controls->m_MethodCombo->currentIndex() == 4) roisize = 5; mitk::Point3D pos = m_MultiWidget->GetCrossPosition(); VecImgType::IndexType crosspos; diffusionImg->GetTimeSlicedGeometry()->WorldToIndex(pos, crosspos); if (!vecimg->GetLargestPossibleRegion().IsInside(crosspos)) { m_Controls->m_Warning->setText(QString("Crosshair position not inside of selected diffusion weighted image. Reinit needed!")); m_Controls->m_Warning->setVisible(true); return; } else m_Controls->m_Warning->setVisible(false); VecImgType::IndexType index; index[0] = crosspos[0] - roisize; index[0] = index[0] < 0 ? 0 : index[0]; index[1] = crosspos[1] - roisize; index[1] = index[1] < 0 ? 0 : index[1]; index[2] = crosspos[2] - roisize; index[2] = index[2] < 0 ? 0 : index[2]; VecImgType::SizeType size; size[0] = roisize*2+1; size[1] = roisize*2+1; size[2] = roisize*2+1; VecImgType::SizeType maxSize = vecimg->GetLargestPossibleRegion().GetSize(); size[0] = index[0]+size[0] > maxSize[0] ? maxSize[0]-index[0] : size[0]; size[1] = index[1]+size[1] > maxSize[1] ? maxSize[1]-index[1] : size[1]; size[2] = index[2]+size[2] > maxSize[2] ? maxSize[2]-index[2] : size[2]; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); VecImgType::IndexType newstart; newstart.Fill(0); VecImgType::RegionType newregion; newregion.SetSize( size ); newregion.SetIndex( newstart ); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( newregion ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(newstart, vecimg->GetPixel(index)); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, crosspos); } else { typedef itk::Image MaskImgType; MaskImgType::Pointer maskItk; CastToItkImage( maskImg, maskItk ); mitk::Point3D pos; pos[0] = 0; pos[1] = 0; pos[2] = 0; VecImgType::IndexType index; index[0] = 0; index[1] = 0; index[2] = 0; VecImgType::SizeType size; size[0] = 1; size[1] = 1; size[2] = 1; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); // iterators over output and input itk::ImageRegionConstIteratorWithIndex vecit(vecimg, vecimg->GetLargestPossibleRegion()); itk::VariableLengthVector avg(vecimg->GetVectorLength()); avg.Fill(0); float numPixels = 0; while ( ! vecit.IsAtEnd() ) { VecImgType::PointType point; vecimg->TransformIndexToPhysicalPoint(vecit.GetIndex(), point); MaskImgType::IndexType index; maskItk->TransformPhysicalPointToIndex(point, index); if(maskItk->GetPixel(index) != 0) { avg += vecit.Get(); numPixels += 1.0; } // update iterators ++vecit; } avg /= numPixels; m_Controls->m_Warning->setText(QString("Averaging ")+QString::number((int)numPixels)+QString(" voxels!")); m_Controls->m_Warning->setVisible(true); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( region ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(index, avg); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, index); } vecimg->SetRegions( vecimg->GetLargestPossibleRegion() ); if (success) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_VisualizeResultsWidget->SetParameters(m_Snap); } } bool QmitkIVIMView::FittIVIM(itk::VectorImage* vecimg, DirContainerType* dirs, float bval, bool multivoxel, OutImgType::IndexType &crosspos) { IVIMFilterType::Pointer filter = IVIMFilterType::New(); filter->SetInput(vecimg); filter->SetGradientDirections(dirs); filter->SetBValue(bval); switch(m_Controls->m_MethodCombo->currentIndex()) { case 0: filter->SetMethod(IVIMFilterType::IVIM_FIT_ALL); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 1: filter->SetMethod(IVIMFilterType::IVIM_DSTAR_FIX); filter->SetDStar(m_Controls->m_DStarLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 2: filter->SetMethod(IVIMFilterType::IVIM_D_THEN_DSTAR); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 3: filter->SetMethod(IVIMFilterType::IVIM_LINEAR_D_THEN_F); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 4: filter->SetMethod(IVIMFilterType::IVIM_REGULARIZED); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetNumberIterations(m_Controls->m_NumItsLabel->text().toInt()); filter->SetLambda(m_Controls->m_LambdaLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; } if(!multivoxel) { filter->SetFitDStar(true); } filter->SetNumberOfThreads(1); filter->SetVerbose(false); filter->SetCrossPosition(crosspos); try{ filter->Update(); m_Snap = filter->GetSnapshot(); m_DStarMap = filter->GetOutput(2); m_DMap = filter->GetOutput(1); m_fMap = filter->GetOutput(0); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; m_Controls->m_Warning->setText(QString("IVIM fit not possible: ")+ex.GetDescription()); m_Controls->m_Warning->setVisible(true); return false; } return true; } void QmitkIVIMView::OutputToDatastorage(std::vector nodes) { // Outputs to Datastorage QString basename(nodes.front()->GetName().c_str()); if(m_Controls->m_CheckDStar->isChecked()) { mitk::Image::Pointer dstarimage = mitk::Image::New(); dstarimage->InitializeByItk(m_DStarMap.GetPointer()); dstarimage->SetVolume(m_DStarMap->GetBufferPointer()); QString newname2 = basename; newname2 = newname2.append("_DStarMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node2=mitk::DataNode::New(); node2->SetData( dstarimage ); node2->SetName(newname2.toAscii()); GetDefaultDataStorage()->Add(node2); } if(m_Controls->m_CheckD->isChecked()) { mitk::Image::Pointer dimage = mitk::Image::New(); dimage->InitializeByItk(m_DMap.GetPointer()); dimage->SetVolume(m_DMap->GetBufferPointer()); QString newname1 = basename; newname1 = newname1.append("_DMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node1=mitk::DataNode::New(); node1->SetData( dimage ); node1->SetName(newname1.toAscii()); GetDefaultDataStorage()->Add(node1); } if(m_Controls->m_Checkf->isChecked()) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(m_fMap.GetPointer()); image->SetVolume(m_fMap->GetBufferPointer()); QString newname0 = basename; newname0 = newname0.append("_fMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetName(newname0.toAscii()); GetDefaultDataStorage()->Add(node); } m_MultiWidget->RequestUpdate(); } void QmitkIVIMView::ChooseMethod() { m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); } void QmitkIVIMView::ClipboardCurveButtonClicked() { if(true) { QString clipboard("Measurement Points\n"); for ( int i=0; isetText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::ClipboardStatisticsButtonClicked() { if ( true ) { QString clipboard( "f \t D \t D* \n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3" ) .arg( m_Snap.currentF, 0, 'f', 10 ) .arg( m_Snap.currentD, 0, 'f', 10 ) .arg( m_Snap.currentDStar, 0, 'f', 10 ) ; QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::Activated() { m_Active = true; } void QmitkIVIMView::Deactivated() { m_Active = false; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui index c818538c87..ee3586448e 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui @@ -1,549 +1,567 @@ QmitkPreprocessingViewControls 0 0 892 - 1079 + 1080 0 0 false QmitkPreprocessingViewControls true Please Select Input Data Raw DWI: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true 0 0 Info 0 0 Qt::ScrollBarAsNeeded Qt::ScrollBarAlwaysOff true 100 true false true b-Value Number of gradients Qt::Horizontal 40 20 false Generate pointset displaying the gradient vectors (applied measurement frame). Show gradients Non diffusion weighted image 0 30 Average and extract all images that were acquired without diffusion weighting. true false If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. Extract B0 Create a 3D+t data set containing all b0 images as timesteps Extract all B0 images without averaging Modify DWI QFrame::NoFrame QFrame::Raised - + + 0 + + + 0 + + + 0 + + 0 Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. 6 2.000000000000000 0.000100000000000 0.001000000000000 Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Merge radius false Multiple acquistions of one gradient direction can be averaged. Due to rounding errors, similar gradients often differ in the last decimal positions. The Merge radius allows to average them by taking all directions within a certain radius into account. Average redundant gradients Qt::Horizontal QFrame::NoFrame QFrame::Raised - + + 0 + + + 0 + + + 0 + + 0 9 Specify desired number of gradients per shell: false Retain only the specified number of gradient directions and according image volumes. The retained directions are spread equally over the half sphere using an iterative energy repulsion strategy. Reduce number of gradients Qt::Horizontal false Sometimes the gradient directions are not located on one half sphere. Mirror gradients to half sphere Merge selected images false Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. Merge selected DWIs 0 0 Measurment frame Qt::Horizontal 40 20 false 0 0 0 0 IBeamCursor true Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff true false false true true 0 false true true New Row New Row New Row New Column New Column New Column false - Apply new mesurement frame + Apply new measurement frame Qt::Vertical 20 40