diff --git a/CMake/PackageDepends/MITK_MatchPoint_Config.cmake b/CMake/PackageDepends/MITK_MatchPoint_Config.cmake new file mode 100644 index 0000000000..7f81ac7e80 --- /dev/null +++ b/CMake/PackageDepends/MITK_MatchPoint_Config.cmake @@ -0,0 +1,2 @@ +list(APPEND ALL_INCLUDE_DIRECTORIES ${MatchPoint_INCLUDE_DIRS}) +list(APPEND ALL_LIBRARIES MAPCore MAPIO MAPDeployment MAPAlgorithms MAPAlgorithmsITK MAPAlgorithmsPlastimatch) diff --git a/CMake/mitkFunctionCreateMatchPointDeployedAlgorithm.cmake b/CMake/mitkFunctionCreateMatchPointDeployedAlgorithm.cmake new file mode 100644 index 0000000000..d44b85510b --- /dev/null +++ b/CMake/mitkFunctionCreateMatchPointDeployedAlgorithm.cmake @@ -0,0 +1,102 @@ +#! +#! Create a Command Line App. +#! +#! \brief This function will create a command line executable and the scripts required to run it +#! +#! \param NAME (required) Name of the algorithm / cmake target +#! \param DEPENDS (optional) Required MITK modules beyond MitkCommandLine +#! \param PACKAGE_DEPENDS (optional) list of "packages" this command line app depends on (e.g. ITK, VTK, etc.) +#! \param CPP_FILES (optional) list of cpp files, if it is not given NAME.cpp is assumed +#! \param INCLUDE_DIRS (optional): All directories that should be added as include dirs to the project +#! \param PROFILE (optional): The profile file that should be used for the algorithm. If not set it is "./.profile". +#! \param ADDITIONAL_LIBS (optional) List of additional private libraries linked to this module. +#! The folder containing the library will be added to the global list of library search paths. +#! \param H_FILES (optional) List of public header files for this module. +#! Assuming that there exists a file called MyApp.cpp, an example call looks like: +#! \code +#! mitkFunctionCreateCommandLineApp( +#! NAME MyApp +#! DEPENDS MitkCore MitkPlanarFigure +#! PACKAGE_DEPENDS ITK VTK +#! ) +#! \endcode +#! + +function(mitkFunctionCreateMatchPointDeployedAlgorithm) + + set(_function_params + NAME # Name of the algorithm/target + ) + + set(_function_multiparams + DEPENDS # list of modules this command line app depends on + PACKAGE_DEPENDS # list of "packages" this command line app depends on (e.g. ITK, VTK, etc.) + CPP_FILES # (optional) list of cpp files, if it is not given NAME.cpp is assumed + INCLUDE_DIRS # include directories: [PUBLIC|PRIVATE|INTERFACE] + ADDITIONAL_LIBS # list of addidtional private libraries linked to this module. + H_FILES # list of header files: [PUBLIC|PRIVATE] + ) + + set(_function_options + + ) + + cmake_parse_arguments(ALG "${_function_options}" "${_function_params}" "${_function_multiparams}" ${ARGN}) + + if( NOT (DEFINED MITK_USE_MatchPoint) OR NOT (${MITK_USE_MatchPoint})) + message(FATAL_ERROR "Need package Matchpoint to deploy MatchPoint Algorithms.") + endif() + + if(NOT ALG_NAME) + message(FATAL_ERROR "NAME argument cannot be empty.") + endif() + + SET(ALG_TARGET "MDRA_${ALG_NAME}") + + if(NOT ALG_CPP_FILES) + set(ALG_CPP_FILES "${ALG_NAME}.cpp") + endif() + + IF(NOT ALG_PROFILE) + set(ALG_PROFILE "${ALG_NAME}.profile") + ENDIF(NOT ALG_PROFILE) + + MESSAGE(STATUS "... generate MDRA profile (from ${ALG_PROFILE})...") + + include(${MatchPoint_SOURCE_DIR}/CMake/mapFunctionCreateAlgorithmProfile.cmake) + CREATE_ALGORITHM_PROFILE(${ALG_NAME} ${ALG_PROFILE}) + + MESSAGE(STATUS "... algorithm UID: ${ALGORITHM_PROFILE_UID}") + + ADD_LIBRARY(${ALG_TARGET} SHARED ${ALG_CPP_FILES} ${ALGORITHM_PROFILE_FILE}) + + SET_TARGET_PROPERTIES(${ALG_TARGET} PROPERTIES + OUTPUT_NAME "mdra-${MatchPoint_VERSION_MAJOR}-${MatchPoint_VERSION_MINOR}_${ALG_NAME}" + OUTPUT_NAME_DEBUG "mdra-D-${MatchPoint_VERSION_MAJOR}-${MatchPoint_VERSION_MINOR}_${ALG_NAME}" + PREFIX "" ) + + mitk_use_modules(TARGET ${ALG_TARGET} + MODULES ${ALG_DEPENDS} + PACKAGES PRIVATE ITK MatchPoint ${ALG_PACKAGE_DEPENDS} + ) + + target_include_directories(${ALG_TARGET} PRIVATE ${ALG_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}) + + if(ALG_ADDITIONAL_LIBS) + target_link_libraries(${ALG_TARGET} PRIVATE ${ALG_ADDITIONAL_LIBS}) + get_property(_mitk_additional_library_search_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) + foreach(_lib_filepath ${ALG_ADDITIONAL_LIBS}) + get_filename_component(_search_path "${_lib_filepath}" PATH) + if(_search_path) + list(APPEND _mitk_additional_library_search_paths "${_search_path}") + endif() + endforeach() + if(_mitk_additional_library_search_paths) + list(REMOVE_DUPLICATES _mitk_additional_library_search_paths) + set_property(GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS ${_mitk_additional_library_search_paths}) + endif() + endif() + + install(TARGETS ${ALG_TARGET} RUNTIME DESTINATION bin LIBRARY DESTINATION bin) + +endfunction() diff --git a/CMake/mitkFunctionCreateModule.cmake b/CMake/mitkFunctionCreateModule.cmake index 7dc9b255bd..df79827d47 100644 --- a/CMake/mitkFunctionCreateModule.cmake +++ b/CMake/mitkFunctionCreateModule.cmake @@ -1,655 +1,655 @@ ################################################################## # # mitk_create_module # #! Creates a module for the automatic module dependency system within MITK. #! #! Example: #! #! \code #! mitk_create_module( #! DEPENDS PUBLIC MitkCore #! PACKAGE_DEPENDS #! PRIVATE Qt5|Xml+Networking #! PUBLIC ITK|Watershed #! WARNINGS_AS_ERRORS #! \endcode #! #! The parameter specifies the name of the module which is used #! to create a logical target name. The parameter is optional in case the #! MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME variable evaluates to TRUE. The #! module name will then be derived from the directory name in which this #! function is called. #! #! If set, the following variables will be used to validate the module name: #! #! MITK_MODULE_NAME_REGEX_MATCH The module name must match this regular expression. #! MITK_MODULE_NAME_REGEX_NOT_MATCH The module name must not match this regular expression. #! #! If the MITK_MODULE_NAME_PREFIX variable is set, the module name will be prefixed #! with its contents. #! #! A modules source files are specified in a separate CMake file usually #! called files.cmake, located in the module root directory. The #! mitk_create_module() macro evaluates the following CMake variables #! from the files.cmake file: #! #! - CPP_FILES A list of .cpp files #! - H_FILES A list of .h files without a corresponding .cpp file #! - TXX_FILES A list of .txx files #! - RESOURCE_FILES A list of files (resources) which are embedded into the module #! - MOC_H_FILES A list of Qt header files which should be processed by the MOC #! - UI_FILES A list of .ui Qt UI files #! - QRC_FILES A list of .qrc Qt resource files #! - DOX_FILES A list of .dox Doxygen files #! #! List of variables available after the function is called: #! - MODULE_NAME #! - MODULE_TARGET #! - MODULE_IS_ENABLED #! - MODULE_SUBPROJECTS #! #! \sa mitk_create_executable #! #! Parameters (all optional): #! #! \param The module name (also used as target name) #! \param FILES_CMAKE File name of a CMake file setting source list variables #! (defaults to files.cmake) #! \param VERSION Module version number, e.g. "1.2.0" #! \param AUTOLOAD_WITH A module target name identifying the module which will #! trigger the automatic loading of this module #! \param DEPRECATED_SINCE Marks this modules as deprecated since #! \param DESCRIPTION A description for this module #! #! Multi-value Parameters (all optional): #! #! \param SUBPROJECTS List of CDash labels #! \param INCLUDE_DIRS Include directories for this module: #! \verbatim #! [[PUBLIC|PRIVATE|INTERFACE] ...]... #! \endverbatim #! The default scope for include directories is PUBLIC. #! \param DEPENDS List of module dependencies: #! \verbatim #! [[PUBLIC|PRIVATE|INTERFACE] ...]... #! \endverbatim #! The default scope for module dependencies is PUBLIC. #! \param PACKAGE_DEPENDS List of public packages dependencies (e.g. Qt, VTK, etc.). #! Package dependencies have the following syntax: #! \verbatim #! [PUBLIC|PRIVATE|INTERFACE] PACKAGE[|COMPONENT1[+COMPONENT2]...] #! \endverbatim #! The default scope for package dependencies is PRIVATE. -#! \param ADDITIONAL_LIBS List of addidtional private libraries linked to this module. +#! \param ADDITIONAL_LIBS List of additional private libraries linked to this module. #! The folder containing the library will be added to the global list of library search paths. #! \param CPP_FILES List of source files for this module. If the list is non-empty, #! the module does not need to provide a files.cmake file or FILES_CMAKE argument. #! \param H_FILES List of public header files for this module. It is recommended to use #! a files.cmake file instead. #! #! Options (optional) #! #! \param FORCE_STATIC Force building this module as a static library #! \param GCC_DEFAULT_VISIBILITY Do not use gcc visibility flags - all #! symbols will be exported #! \param NO_INIT Do not create CppMicroServices initialization code #! \param NO_FEATURE_INFO Do not create a feature info by calling add_feature_info() #! \param WARNINGS_AS_ERRORS Treat compiler warnings as errors # ################################################################## function(mitk_create_module) set(_macro_params VERSION # module version number, e.g. "1.2.0" EXPORT_DEFINE # export macro name for public symbols of this module (DEPRECATED) AUTOLOAD_WITH # a module target name identifying the module which will trigger the # automatic loading of this module FILES_CMAKE # file name of a CMake file setting source list variables # (defaults to files.cmake) DEPRECATED_SINCE # marks this modules as deprecated DESCRIPTION # a description for this module ) set(_macro_multiparams SUBPROJECTS # list of CDash labels INCLUDE_DIRS # include directories: [PUBLIC|PRIVATE|INTERFACE] INTERNAL_INCLUDE_DIRS # include dirs internal to this module (DEPRECATED) DEPENDS # list of modules this module depends on: [PUBLIC|PRIVATE|INTERFACE] DEPENDS_INTERNAL # list of modules this module internally depends on (DEPRECATED) PACKAGE_DEPENDS # list of "packages this module depends on (e.g. Qt, VTK, etc.): [PUBLIC|PRIVATE|INTERFACE] TARGET_DEPENDS # list of CMake targets this module should depend on ADDITIONAL_LIBS # list of addidtional private libraries linked to this module. CPP_FILES # list of cpp files H_FILES # list of header files: [PUBLIC|PRIVATE] ) set(_macro_options 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_DEFAULT_INCLUDE_DIRS # do not add default include directories like "include" or "." NO_INIT # do not create CppMicroServices initialization code NO_FEATURE_INFO # do not create a feature info by calling add_feature_info() WARNINGS_AS_ERRORS # treat all compiler warnings as errors EXECUTABLE # create an executable; do not use directly, use mitk_create_executable() instead C_MODULE # compile all source files as C sources CXX_MODULE # compile all source files as C++ sources ) cmake_parse_arguments(MODULE "${_macro_options}" "${_macro_params}" "${_macro_multiparams}" ${ARGN}) set(MODULE_NAME ${MODULE_UNPARSED_ARGUMENTS}) # ----------------------------------------------------------------- # Sanity checks if(NOT MODULE_NAME) if(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME) get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) else() message(SEND_ERROR "The module name must not be empty") endif() endif() set(_deprecated_args INTERNAL_INCLUDE_DIRS DEPENDS_INTERNAL EXPORT_DEFINE TARGET_DEPENDS HEADERS_ONLY) foreach(_deprecated_arg ${_deprecated_args}) if(MODULE_${_deprecated_arg}) message(WARNING "The ${_deprecated_arg} argument is deprecated") endif() endforeach() set(_module_type module) set(_Module_type Module) if(MODULE_EXECUTABLE) set(_module_type executable) set(_Module_type Executable) endif() if(MITK_MODULE_NAME_REGEX_MATCH) if(NOT ${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_MATCH}) message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" does not match the regular expression \"${MITK_MODULE_NAME_REGEX_MATCH}\".") endif() endif() if(MITK_MODULE_NAME_REGEX_NOT_MATCH) if(${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_NOT_MATCH}) message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" must not match the regular expression \"${MITK_MODULE_NAME_REGEX_NOT_MATCH}\".") endif() endif() if(MITK_MODULE_NAME_PREFIX AND NOT MODULE_NAME MATCHES "^${MITK_MODULE_NAME_PREFIX}.*$") set(MODULE_NAME "${MITK_MODULE_NAME_PREFIX}${MODULE_NAME}") endif() if(NOT MODULE_FILES_CMAKE) set(MODULE_FILES_CMAKE files.cmake) endif() if(NOT IS_ABSOLUTE ${MODULE_FILES_CMAKE}) set(MODULE_FILES_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FILES_CMAKE}) 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 if module should be build set(MODULE_TARGET ${MODULE_NAME}) # 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) # first of all we check for the dependencies _mitk_parse_package_args(${MODULE_PACKAGE_DEPENDS}) mitk_check_module_dependencies(MODULES ${MODULE_DEPENDS} PACKAGES ${PACKAGE_NAMES} MISSING_DEPENDENCIES_VAR _MISSING_DEP PACKAGE_DEPENDENCIES_VAR PACKAGE_NAMES) if(_MISSING_DEP) if(MODULE_NO_FEATURE_INFO) message("${_Module_type} ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}") endif() set(MODULE_IS_ENABLED 0) else() set(MODULE_IS_ENABLED 1) # now check for every package if it is enabled. This overlaps a bit with # MITK_CHECK_MODULE ... foreach(_package ${PACKAGE_NAMES}) if((DEFINED MITK_USE_${_package}) AND NOT (MITK_USE_${_package})) message("${_Module_type} ${MODULE_NAME} won't be built. Turn on MITK_USE_${_package} if you want to use it.") set(MODULE_IS_ENABLED 0) break() endif() endforeach() endif() endif() # ----------------------------------------------------------------- # Start creating the module 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_CPP ) set(Q${KITNAME}_GENERATED_MOC_CPP ) set(Q${KITNAME}_GENERATED_QRC_CPP ) set(Q${KITNAME}_GENERATED_UI_CPP ) # 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() endif() set(_module_autoload_meta_target "${CMAKE_PROJECT_NAME}-autoload") # create a meta-target if it does not already exist if(NOT TARGET ${_module_autoload_meta_target}) add_custom_target(${_module_autoload_meta_target}) endif() if(NOT MODULE_EXPORT_DEFINE) set(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT) endif() 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) if (EXISTS ${MODULE_FILES_CMAKE}) include(${MODULE_FILES_CMAKE}) endif() if(MODULE_CPP_FILES) list(APPEND CPP_FILES ${MODULE_CPP_FILES}) endif() if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src") # Preprend the "src" directory to the cpp file list set(_cpp_files ${CPP_FILES}) set(CPP_FILES ) foreach(_cpp_file ${_cpp_files}) list(APPEND CPP_FILES "src/${_cpp_file}") endforeach() endif() if(CPP_FILES OR RESOURCE_FILES OR UI_FILES OR MOC_H_FILES OR QRC_FILES) set(MODULE_HEADERS_ONLY 0) if(MODULE_C_MODULE) set_source_files_properties(${CPP_FILES} PROPERTIES LANGUAGE C) elseif(MODULE_CXX_MODULE) set_source_files_properties(${CPP_FILES} PROPERTIES LANGUAGE CXX) endif() else() set(MODULE_HEADERS_ONLY 1) if(MODULE_AUTOLOAD_WITH) message(SEND_ERROR "A headers only module cannot be auto-loaded") endif() endif() set(module_c_flags ) set(module_c_flags_debug ) set(module_c_flags_release ) set(module_cxx_flags ) set(module_cxx_flags_debug ) set(module_cxx_flags_release ) if(MODULE_GCC_DEFAULT_VISIBILITY OR NOT CMAKE_COMPILER_IS_GNUCXX) # We only support hidden visibility for gcc for now. Clang 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 set(CMAKE_CXX_VISIBILITY_PRESET default) set(CMAKE_VISIBILITY_INLINES_HIDDEN 0) else() set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) endif() if(MODULE_WARNINGS_AS_ERRORS) if(MSVC_VERSION) mitkFunctionCheckCAndCXXCompilerFlags("/WX" module_c_flags module_cxx_flags) else() mitkFunctionCheckCAndCXXCompilerFlags(-Werror module_c_flags module_cxx_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 additionally 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). mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=static-member-init" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unknown-warning" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=gnu" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=inconsistent-missing-override" module_c_flags module_cxx_flags) endif() endif(MODULE_WARNINGS_AS_ERRORS) if(MODULE_FORCE_STATIC) set(_STATIC STATIC) else() set(_STATIC ) endif(MODULE_FORCE_STATIC) if(NOT MODULE_HEADERS_ONLY) if(NOT MODULE_NO_INIT OR RESOURCE_FILES) find_package(CppMicroServices QUIET NO_MODULE REQUIRED) endif() if(NOT MODULE_NO_INIT) usFunctionGenerateModuleInit(CPP_FILES) endif() set(binary_res_files ) set(source_res_files ) if(RESOURCE_FILES) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/resource") set(res_dir resource) elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Resources") set(res_dir Resources) else() message(SEND_ERROR "Resources specified but ${CMAKE_CURRENT_SOURCE_DIR}/resource directory not found.") endif() foreach(res_file ${RESOURCE_FILES}) if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}/${res_file}) list(APPEND binary_res_files "${res_file}") else() list(APPEND source_res_files "${res_file}") endif() endforeach() # Add a source level dependencies on resource files usFunctionGetResourceSource(TARGET ${MODULE_TARGET} OUT CPP_FILES) endif() endif() if(MITK_USE_QT) if(UI_FILES) qt5_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES}) endif() if(MOC_H_FILES) qt5_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) endif() if(QRC_FILES) qt5_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES}) endif() endif() set(Q${KITNAME}_GENERATED_CPP ${Q${KITNAME}_GENERATED_CPP} ${Q${KITNAME}_GENERATED_UI_CPP} ${Q${KITNAME}_GENERATED_MOC_CPP} ${Q${KITNAME}_GENERATED_QRC_CPP}) mitkFunctionOrganizeSources( 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() # --------------------------------------------------------------- # Create the actual module target if(MODULE_HEADERS_ONLY) add_library(${MODULE_TARGET} INTERFACE) else() if(MODULE_EXECUTABLE) add_executable(${MODULE_TARGET} ${MODULE_CPP_FILES} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP} ${DOX_FILES} ${UI_FILES} ${QRC_FILES}) set(_us_module_name main) else() add_library(${MODULE_TARGET} ${_STATIC} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP} ${DOX_FILES} ${UI_FILES} ${QRC_FILES}) set(_us_module_name ${MODULE_TARGET}) endif() # Apply properties to the module target. target_compile_definitions(${MODULE_TARGET} PRIVATE US_MODULE_NAME=${_us_module_name}) if(MODULE_C_MODULE) if(module_c_flags) string(REPLACE " " ";" module_c_flags "${module_c_flags}") target_compile_options(${MODULE_TARGET} PRIVATE ${module_c_flags}) endif() if(module_c_flags_debug) string(REPLACE " " ";" module_c_flags_debug "${module_c_flags_debug}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_c_flags_debug}>) endif() if(module_c_flags_release) string(REPLACE " " ";" module_c_flags_release "${module_c_flags_release}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_c_flags_release}>) endif() else() if(module_cxx_flags) string(REPLACE " " ";" module_cxx_flags "${module_cxx_flags}") target_compile_options(${MODULE_TARGET} PRIVATE ${module_cxx_flags}) endif() if(module_cxx_flags_debug) string(REPLACE " " ";" module_cxx_flags_debug "${module_cxx_flags_debug}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_cxx_flags_debug}>) endif() if(module_cxx_flags_release) string(REPLACE " " ";" module_cxx_flags_release "${module_cxx_flags_release}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_cxx_flags_release}>) endif() endif() set_property(TARGET ${MODULE_TARGET} PROPERTY US_MODULE_NAME ${_us_module_name}) if(MINGW) target_link_libraries(${MODULE_TARGET} ssp) # add stack smash protection lib endif() # Add additional library search directories to a global property which # can be evaluated by other CMake macros, e.g. our install scripts. if(MODULE_ADDITIONAL_LIBS) target_link_libraries(${MODULE_TARGET} PRIVATE ${MODULE_ADDITIONAL_LIBS}) get_property(_mitk_additional_library_search_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) foreach(_lib_filepath ${MODULE_ADDITIONAL_LIBS}) get_filename_component(_search_path "${_lib_filepath}" PATH) if(_search_path) list(APPEND _mitk_additional_library_search_paths "${_search_path}") endif() endforeach() if(_mitk_additional_library_search_paths) list(REMOVE_DUPLICATES _mitk_additional_library_search_paths) set_property(GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS ${_mitk_additional_library_search_paths}) endif() endif() # 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_TARGET}) if(MODULE_AUTOLOAD_WITH) # for auto-loaded modules, adapt the output directory add_dependencies(${_module_autoload_meta_target} ${MODULE_TARGET}) 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_TARGET} PROPERTIES ${_module_output_prop} ${_module_output_dir}/${MODULE_AUTOLOAD_WITH}) else() set_target_properties(${MODULE_TARGET} PROPERTIES ${_module_output_prop} ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH}) endif() set_target_properties(${MODULE_TARGET} 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_TARGET}) endif() if(binary_res_files) usFunctionAddResources(TARGET ${MODULE_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${res_dir} FILES ${binary_res_files}) endif() if(source_res_files) usFunctionAddResources(TARGET ${MODULE_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${res_dir} FILES ${source_res_files}) endif() if(binary_res_files OR source_res_files) usFunctionEmbedResources(TARGET ${MODULE_TARGET}) endif() if(MODULE_DEPRECATED_SINCE) set_property(TARGET ${MODULE_TARGET} PROPERTY MITK_MODULE_DEPRECATED_SINCE ${MODULE_DEPRECATED_SINCE}) endif() # create export macros if (NOT MODULE_EXECUTABLE) set(_export_macro_name ) if(MITK_LEGACY_EXPORT_MACRO_NAME) set(_export_macro_names EXPORT_MACRO_NAME ${MODULE_EXPORT_DEFINE} NO_EXPORT_MACRO_NAME ${MODULE_NAME}_NO_EXPORT DEPRECATED_MACRO_NAME ${MODULE_NAME}_DEPRECATED NO_DEPRECATED_MACRO_NAME ${MODULE_NAME}_NO_DEPRECATED ) endif() generate_export_header(${MODULE_NAME} ${_export_macro_names} EXPORT_FILE_NAME ${MODULE_NAME}Exports.h ) endif() target_include_directories(${MODULE_TARGET} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) endif() # --------------------------------------------------------------- # Properties for both header-only and compiled modules if(MODULE_HEADERS_ONLY) set(_module_property_type INTERFACE) else() set(_module_property_type PUBLIC) endif() if(MODULE_TARGET_DEPENDS) add_dependencies(${MODULE_TARGET} ${MODULE_TARGET_DEPENDS}) endif() if(MODULE_SUBPROJECTS AND NOT MODULE_HEADERS_ONLY) set_property(TARGET ${MODULE_TARGET} PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK) foreach(subproject ${MODULE_SUBPROJECTS}) add_dependencies(${subproject} ${MODULE_TARGET}) endforeach() endif() set(DEPENDS "${MODULE_DEPENDS}") if(NOT MODULE_NO_INIT AND NOT MODULE_HEADERS_ONLY) # Add a CppMicroServices dependency implicitly, since it is # needed for the generated "module initialization" code. set(DEPENDS "CppMicroServices;${DEPENDS}") endif() if(DEPENDS OR MODULE_PACKAGE_DEPENDS) mitk_use_modules(TARGET ${MODULE_TARGET} MODULES ${DEPENDS} PACKAGES ${MODULE_PACKAGE_DEPENDS} ) endif() if(NOT MODULE_C_MODULE) target_compile_features(${MODULE_TARGET} ${_module_property_type} ${MITK_CXX_FEATURES}) endif() # add include directories if(MODULE_INTERNAL_INCLUDE_DIRS) target_include_directories(${MODULE_TARGET} PRIVATE ${MODULE_INTERNAL_INCLUDE_DIRS}) endif() if(NOT MODULE_NO_DEFAULT_INCLUDE_DIRS) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(${MODULE_TARGET} ${_module_property_type} include) else() target_include_directories(${MODULE_TARGET} ${_module_property_type} .) endif() if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src) target_include_directories(${MODULE_TARGET} PRIVATE src) endif() endif() target_include_directories(${MODULE_TARGET} ${_module_property_type} ${MODULE_INCLUDE_DIRS}) endif() # ----------------------------------------------------------------- # Record missing dependency information if(_MISSING_DEP) if(MODULE_DESCRIPTION) set(MODULE_DESCRIPTION "${MODULE_DESCRIPTION} (missing dependencies: ${_MISSING_DEP})") else() set(MODULE_DESCRIPTION "(missing dependencies: ${_MISSING_DEP})") endif() endif() if(NOT MODULE_NO_FEATURE_INFO) add_feature_info(${MODULE_NAME} MODULE_IS_ENABLED "${MODULE_DESCRIPTION}") endif() set(MODULE_NAME ${MODULE_NAME} PARENT_SCOPE) set(MODULE_TARGET ${MODULE_TARGET} PARENT_SCOPE) set(MODULE_IS_ENABLED ${MODULE_IS_ENABLED} PARENT_SCOPE) set(MODULE_SUBPROJECTS ${MODULE_SUBPROJECTS} PARENT_SCOPE) endfunction() diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake index 309a182e73..b0599e3edd 100644 --- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake +++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake @@ -1,167 +1,175 @@ macro(_find_package package_name) find_package(${package_name} REQUIRED PATHS ${${package_name}_DIR} PATH_SUFFIXES ${package_name} NO_DEFAULT_PATH NO_MODULE QUIET) if(NOT ${package_name}_FOUND) find_package(${package_name} REQUIRED) endif() endmacro() function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir) set(_dir_candidates "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}" "${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins" ) if(MITK_EXTERNAL_PROJECT_PREFIX) list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/bin" "${MITK_EXTERNAL_PROJECT_PREFIX}/lib" ) endif() # Determine the Qt5 library installation prefix set(_qmake_location ) if(MITK_USE_QT AND TARGET ${Qt5Core_QMAKE_EXECUTABLE}) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) endif() if(_qmake_location) if(NOT _qt_install_libs) if(WIN32) execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) else() execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS OUTPUT_VARIABLE _qt_install_libs OUTPUT_STRIP_TRAILING_WHITESPACE) endif() file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs) set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE) endif() if(_qt_install_libs) list(APPEND _dir_candidates ${_qt_install_libs}) endif() elseif(MITK_USE_QT) message(WARNING "The qmake executable could not be found.") endif() get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) if(MITK_USE_HDF5) _find_package(HDF5) get_target_property(_location hdf5 LOCATION) get_filename_component(_location ${_location} PATH) list(APPEND _additional_paths ${_location}) # This is a work-around. The hdf5-config.cmake file is not robust enough # to be included several times via find_pakcage calls. set(HDF5_LIBRARIES ${HDF5_LIBRARIES} PARENT_SCOPE) endif() if(MITK_USE_Vigra) # we cannot use _find_package(Vigra) here because the vigra-config.cmake file # always includes the target-exports files without using an include guard. This # would lead to errors when another find_package(Vigra) call is processed. The # (bad) assumption here is that for the time being, only the Classification module # is using Vigra. if(UNIX) list(APPEND _additional_paths ${Vigra_DIR}/lib) else() list(APPEND _additional_paths ${Vigra_DIR}/bin) endif() endif() if(_additional_paths) list(APPEND _dir_candidates ${_additional_paths}) endif() # The code below is sub-optimal. It makes assumptions about # the structure of the build directories, pointed to by # the *_DIR variables. Instead, we should rely on package # specific "LIBRARY_DIRS" variables, if they exist. if(WIN32) if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/bin") endif() list(APPEND _dir_candidates "${ITK_DIR}/bin") else() if(SOFA_DIR) list(APPEND _dir_candidates "${SOFA_DIR}/lib") endif() endif() + if(MITK_USE_MatchPoint) + if(WIN32) + list(APPEND _dir_candidates "${MatchPoint_DIR}/bin") + else() + list(APPEND _dir_candidates "${MatchPoint_DIR}/lib") + endif() + endif() + if(OpenCV_DIR) set(_opencv_link_directories "${OpenCV_LIB_DIR_DBG}" "${OpenCV_LIB_DIR_OPT}" "${OpenCV_3RDPARTY_LIB_DIR_DBG}" "${OpenCV_3RDPARTY_LIB_DIR_OPT}") list(REMOVE_DUPLICATES _opencv_link_directories) if(WIN32) foreach(_opencv_link_directory ${_opencv_link_directories}) list(APPEND _dir_candidates "${_opencv_link_directory}/../bin") endforeach() else() list(APPEND _dir_candidates ${_opencv_link_directories}) endif() endif() if(MITK_USE_Python) list(APPEND _dir_candidates "${CTK_DIR}/CMakeExternals/Install/bin") list(APPEND _dir_candidates "${MITK_EXTERNAL_PROJECT_PREFIX}/lib/python2.7/bin") endif() if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD) list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin") endif() if(MITK_USE_CTK) list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}") foreach(_ctk_library ${CTK_LIBRARIES}) if(${_ctk_library}_LIBRARY_DIRS) list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}") endif() endforeach() endif() if(MITK_USE_BLUEBERRY) if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") else() list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") endif() endif() endif() if(MITK_LIBRARY_DIRS) list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS}) endif() list(REMOVE_DUPLICATES _dir_candidates) set(_search_dirs ) foreach(_dir ${_dir_candidates}) if(EXISTS "${_dir}/${intermediate_dir}") list(APPEND _search_dirs "${_dir}/${intermediate_dir}") else() list(APPEND _search_dirs "${_dir}") endif() endforeach() # Special handling for "internal" search dirs. The intermediate directory # might not have been created yet, so we can't check for its existence. # Hence we just add it for Windows without checking. set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins") if(WIN32) foreach(_dir ${_internal_search_dirs}) set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs}) endforeach() else() set(_search_dirs ${_internal_search_dirs} ${_search_dirs}) endif() list(REMOVE_DUPLICATES _search_dirs) set(${search_path} ${_search_dirs} PARENT_SCOPE) endfunction() diff --git a/CMake/mitkInstallRules.cmake b/CMake/mitkInstallRules.cmake index f41b0e21f9..a185d391e6 100644 --- a/CMake/mitkInstallRules.cmake +++ b/CMake/mitkInstallRules.cmake @@ -1,142 +1,152 @@ MITK_INSTALL(FILES "${MITK_SOURCE_DIR}/mitk.ico") MITK_INSTALL(FILES "${MITK_SOURCE_DIR}/mitk.bmp") # Install CTK Qt (designer) plugins if(MITK_USE_CTK) if(EXISTS ${CTK_QTDESIGNERPLUGINS_DIR}) set(_qtplugin_install_destinations) if(MACOSX_BUNDLE_NAMES) foreach(bundle_name ${MACOSX_BUNDLE_NAMES}) list(APPEND _qtplugin_install_destinations ${bundle_name}.app/Contents/MacOS/${_install_DESTINATION}/plugins/designer) endforeach() else() list(APPEND _qtplugin_install_destinations bin/plugins/designer) endif() set(_ctk_qt_plugin_folder_release) set(_ctk_qt_plugin_folder_debug) if(NOT CMAKE_CFG_INTDIR STREQUAL ".") set(_ctk_qt_plugin_folder_release "Release/") set(_ctk_qt_plugin_folder_debug "Debug/") endif() foreach(_qtplugin_install_dir ${_qtplugin_install_destinations}) install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/${_ctk_qt_plugin_folder_release}" DESTINATION ${_qtplugin_install_dir} CONFIGURATIONS Release ) install(DIRECTORY "${CTK_QTDESIGNERPLUGINS_DIR}/designer/${_ctk_qt_plugin_folder_debug}" DESTINATION ${_qtplugin_install_dir} CONFIGURATIONS Debug ) endforeach() endif() endif() # related to MITK:T19679 if(MACOSX_BUNDLE_NAMES) foreach(bundle_name ${MACOSX_BUNDLE_NAMES}) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) get_filename_component(_qmake_path "${_qmake_location}" DIRECTORY) install(FILES "${_qmake_path}/../plugins/platforms/libqcocoa.dylib" DESTINATION "${bundle_name}.app/Contents/MacOS/platforms" CONFIGURATIONS Release) install(FILES "${_qmake_path}/../plugins/sqldrivers/libqsqlite.dylib" DESTINATION "${bundle_name}.app/Contents/MacOS/sqldrivers" CONFIGURATIONS Release) install(FILES "${_qmake_path}/../plugins/iconengines/libqsvgicon.dylib" DESTINATION "${bundle_name}.app/Contents/MacOS/iconengines" CONFIGURATIONS Release) # related to MITK:T19679-InstallQtWebEnginProcess if(MITK_USE_QT_WEBENGINE) get_filename_component(ABS_DIR_HELPERS "${_qmake_path}/../lib/QtWebEngineCore.framework/Helpers" REALPATH) install(DIRECTORY ${ABS_DIR_HELPERS} DESTINATION "${bundle_name}.app/Contents/Frameworks/QtWebEngineCore.framework/" CONFIGURATIONS Release) endif() endforeach() endif() if(WIN32) if(MITK_USE_QT) get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION) get_filename_component(_qmake_path "${_qmake_location}" DIRECTORY) install(FILES "${_qmake_path}/../plugins/platforms/qwindows.dll" DESTINATION "bin/plugins/platforms" CONFIGURATIONS Release) install(FILES "${_qmake_path}/../plugins/sqldrivers/qsqlite.dll" DESTINATION "bin/plugins/sqldrivers" CONFIGURATIONS Release) install(FILES "${_qmake_path}/../plugins/imageformats/qsvg.dll" DESTINATION "bin/plugins/imageformats" CONFIGURATIONS Release) if(MITK_USE_QT_WEBENGINE) MITK_INSTALL( FILES "${_qmake_path}/QtWebEngineProcess.exe") endif() install(DIRECTORY "${_qmake_path}/../resources/" DESTINATION "bin/resources/" CONFIGURATIONS Release) install(FILES "${_qmake_path}/../plugins/platforms/qwindowsd.dll" DESTINATION "bin/plugins/platforms" CONFIGURATIONS Debug) install(FILES "${_qmake_path}/../plugins/sqldrivers/qsqlited.dll" DESTINATION "bin/plugins/sqldrivers" CONFIGURATIONS Debug) install(FILES "${_qmake_path}/../plugins/imageformats/qsvgd.dll" DESTINATION "bin/plugins/imageformats" CONFIGURATIONS Debug) install(DIRECTORY "${_qmake_path}/../resources/" DESTINATION "bin/resources/" CONFIGURATIONS Debug) endif() #DCMTK Dlls install target (shared libs on gcc only) if(MINGW AND DCMTK_ofstd_LIBRARY) set(_dcmtk_libs ${DCMTK_dcmdata_LIBRARY} ${DCMTK_dcmimgle_LIBRARY} ${DCMTK_dcmnet_LIBRARY} ${DCMTK_ofstd_LIBRARY} ) foreach(_dcmtk_lib ${_dcmtk_libs}) MITK_INSTALL(FILES ${_dcmtk_lib} ) endforeach() endif() #MinGW dll if(MINGW) find_library(MINGW_RUNTIME_DLL "mingwm10.dll" HINTS ${CMAKE_FIND_ROOT_PATH}/sys-root/mingw/bin) if(MINGW_RUNTIME_DLL) MITK_INSTALL(FILES ${MINGW_RUNTIME_DLL} ) else() message(SEND_ERROR "Could not find mingwm10.dll which is needed for a proper install") endif() find_library(MINGW_GCC_RUNTIME_DLL "libgcc_s_dw2-1.dll" HINTS ${CMAKE_FIND_ROOT_PATH}/sys-root/mingw/bin) if(MINGW_GCC_RUNTIME_DLL) MITK_INSTALL(FILES ${MINGW_GCC_RUNTIME_DLL} ) else() message(SEND_ERROR "Could not find libgcc_s_dw2-1.dll which is needed for a proper install") endif() endif() else() #DCMTK Dlls install target (shared libs on gcc only) if(DCMTK_ofstd_LIBRARY) set(_dcmtk_libs ${DCMTK_dcmdata_LIBRARY} ${DCMTK_dcmimgle_LIBRARY} ${DCMTK_dcmnet_LIBRARY} ${DCMTK_ofstd_LIBRARY} ) foreach(_dcmtk_lib ${_dcmtk_libs}) #MITK_INSTALL(FILES ${_dcmtk_lib} DESTINATION lib) endforeach() endif() endif() + +#install Matchpoint libs that are currently not auto detected +if(MITK_USE_MatchPoint) + install(DIRECTORY "${MITK_EXTERNAL_PROJECT_PREFIX}/bin/" + DESTINATION "bin" + FILES_MATCHING PATTERN "MAPUtilities*") + install(DIRECTORY "${MITK_EXTERNAL_PROJECT_PREFIX}/bin/" + DESTINATION "bin" + FILES_MATCHING PATTERN "MAPAlgorithms*") +endif() diff --git a/CMakeExternals/ITK-4.9.0.patch b/CMakeExternals/ITK-4.9.0.patch index d210df02f0..a41e56f5fa 100644 --- a/CMakeExternals/ITK-4.9.0.patch +++ b/CMakeExternals/ITK-4.9.0.patch @@ -1,21 +1,31 @@ diff --git a/Modules/ThirdParty/GDCM/CMakeLists.txt b/Modules/ThirdParty/GDCM/CMakeLists.txt --- a/Modules/ThirdParty/GDCM/CMakeLists.txt +++ b/Modules/ThirdParty/GDCM/CMakeLists.txt @@ -4,7 +4,7 @@ if(ITK_USE_SYSTEM_GDCM) if(ITK_USE_SYSTEM_GDCM) set(ITKGDCM_SYSTEM_INCLUDE_DIRS ${GDCM_INCLUDE_DIRS}) set(ITKGDCM_SYSTEM_LIBRARY_DIRS ${GDCM_LIBRARY_DIRS}) - set(ITKGDCM_LIBRARIES gdcmDICT gdcmMSFF) + set(ITKGDCM_LIBRARIES gdcmDICT gdcmMSFF gdcmDSED) set(ITKGDCM_NO_SRC 1) # When this module is loaded by an app, load GDCM too. @@ -42,7 +42,7 @@ else() endif() endif() endif() - set(ITKGDCM_LIBRARIES gdcmDICT gdcmMSFF ) + set(ITKGDCM_LIBRARIES gdcmDICT gdcmMSFF gdcmDSED) endif() itk_module_impl() +diff --git a/Modules/ThirdParty/Expat/src/expat/CMakeLists.txt b/Modules/ThirdParty/Expat/src/expat/CMakeLists.txt +--- a/Modules/ThirdParty/Expat/src/expat/CMakeLists.txt ++++ b/Modules/ThirdParty/Expat/src/expat/CMakeLists.txt +@@ -38,5 +38,6 @@ INSTALL(TARGETS ITKEXPAT + INSTALL(FILES + ${ITK3P_EXPAT_BINARY_DIR}/expatDllConfig.h + ${ITK3P_EXPAT_SOURCE_DIR}/expat.h ++ ${ITK3P_EXPAT_SOURCE_DIR}/itk_expat_mangle.h + DESTINATION ${ITK3P_INSTALL_INCLUDE_DIR} # TODO: itk_expat.h #include "itkexpat/expat.h" + COMPONENT Development) diff --git a/CMakeExternals/MatchPoint.cmake b/CMakeExternals/MatchPoint.cmake new file mode 100644 index 0000000000..2fd129a6ae --- /dev/null +++ b/CMakeExternals/MatchPoint.cmake @@ -0,0 +1,61 @@ +#----------------------------------------------------------------------------- +# MatchPoint +#----------------------------------------------------------------------------- + +set(MatchPoint_SOURCE_DIR "" CACHE PATH "Location of the MatchPoint source directory") +mark_as_advanced(MatchPoint_SOURCE_DIR) + +# Sanity checks +if(DEFINED MatchPoint_DIR AND NOT EXISTS ${MatchPoint_DIR}) + message(FATAL_ERROR "MatchPoint_DIR variable is defined but corresponds to non-existing directory") +endif() + +if(NOT MatchPoint_DIR AND MatchPoint_SOURCE_DIR AND NOT EXISTS ${MatchPoint_SOURCE_DIR}) + message(FATAL_ERROR "MatchPoint_SOURCE_DIR variable is defined but corresponds to non-existing directory") +endif() + +set(proj MatchPoint) +set(proj_DEPENDENCIES ITK) + +set(MatchPoint_DEPENDS ${proj}) + +if(NOT MatchPoint_DIR) + + if(MatchPoint_SOURCE_DIR) + set(download_step SOURCE_DIR ${MatchPoint_SOURCE_DIR}) + else() + set(download_step + URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/MatchPoint_rev1481.tar.gz + URL_MD5 82b9b1bb3f909f2e00397e285ce8c981 + ) + endif() + + ExternalProject_Add(${proj} + ${download_step} + # INSTALL_COMMAND "${CMAKE_COMMAND} -P cmake_install.cmake" + CMAKE_GENERATOR ${gen} + CMAKE_ARGS + ${ep_common_args} + ${additional_cmake_args} + -DBUILD_TESTING:BOOL=OFF + -DITK_DIR:PATH=${ITK_DIR} #/src/ITK-build + -DMAP_USE_SYSTEM_GDCM:BOOL=ON + -DMAP_DISABLE_ITK_IO_FACTORY_AUTO_REGISTER:BOOL=ON + -DMAP_WRAP_Plastimatch:BOOL=ON + -DGDCM_DIR:PATH=${GDCM_DIR} + CMAKE_CACHE_ARGS + ${ep_common_cache_args} + CMAKE_CACHE_DEFAULT_ARGS + ${ep_common_cache_default_args} + DEPENDS ${proj_DEPENDENCIES} + ) + + ExternalProject_Get_Property(${proj} binary_dir) + set(${proj}_DIR ${binary_dir}) + mitkFunctionInstallExternalCMakeProject(${proj}) + +else() + + mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") + +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ad206a15..5e6fe2540f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,1412 +1,1416 @@ set(MITK_CMAKE_MINIMUM_REQUIRED_VERSION 3.2) cmake_minimum_required(VERSION ${MITK_CMAKE_MINIMUM_REQUIRED_VERSION}) #----------------------------------------------------------------------------- # See http://www.cmake.org/cmake/help/v3.2/manual/cmake-policies.7.html for details #----------------------------------------------------------------------------- set(project_policies ) foreach(policy ${project_policies}) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() endforeach() #----------------------------------------------------------------------------- # Superbuild Option - Enabled by default #----------------------------------------------------------------------------- option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON) if(MITK_USE_SUPERBUILD) project(MITK-superbuild) set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR}) set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR}) else() project(MITK VERSION 2016.03.99) endif() #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake) set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR} ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- # Standard CMake macros include(FeatureSummary) include(CTestUseLaunchers) include(CMakeParseArguments) include(FindPackageHandleStandardArgs) # MITK macros include(mitkFunctionGetGccVersion) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionSuppressWarnings) # includes several functions include(mitkMacroEmptyExternalProject) include(mitkFunctionGenerateProjectXml) include(mitkFunctionEnableBuildConfiguration) include(mitkFunctionWhitelists) include(mitkFunctionAddExternalProject) SUPPRESS_VC_DEPRECATED_WARNINGS() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # Check miminum Mac OS X version #----------------------------------------------------------------------------- # The minimum supported Mac OS X version is 10.9. If you use a version less than 10.9, there is no guarantee that the build still works. if(APPLE) exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE osx_version) if (osx_version VERSION_LESS "10.9") message(WARNING "Detected OS X version \"${osx_version}\" is not supported anymore. Minimum required OS X version is 10.9 or greater.") endif() if (CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9) message(WARNING "Detected OS X deployment target \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" is not supported anymore. Minimum required OS X version is 10.9 or greater.") endif() endif() #----------------------------------------------------------------------------- # Check miminum compiler versions #----------------------------------------------------------------------------- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # require at least gcc 4.7.3 as provided by ppa:ubuntu-toolchain-r/test for Ubuntu 12.04 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7.3) message(FATAL_ERROR "GCC version must be at least 4.7.3 If you are using Ubuntu 12.04, you can easily install gcc and g++ 4.7.3 (or any later version available) in addition to your version ${CMAKE_CXX_COMPILER_VERSION}: sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-4.7 g++-4.7 Make sure to explicitly specify these compilers when configuring MITK: CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-4.7 CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-4.7 For more information on the proposed PPA see the Toolchain Updates section of https://wiki.ubuntu.com/ToolChain.") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # require at least clang 3.4 as provided by Ubuntu 12.04 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) message(FATAL_ERROR "Clang version must be at least 3.4") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") # require at least clang 5.0 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "Apple Clang version must be at least 5.0") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # require at least Visual Studio 2012 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0.61030.0) message(FATAL_ERROR "Microsoft Visual Studio 2012 Update 4 or newer required (MSVC 17.0.61030.0)") endif() else() message(WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang (Linux or Apple), GCC and MSVC.") endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) else() set(GCC_VERSION 0) endif() set(MITK_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS 0) set(CMAKE_CXX_STANDARD ${MITK_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED 1) # This is necessary to avoid problems with compile feature checks. # CMAKE_CXX_STANDARD seems to only set the -std=c++11 flag for targets. # However, compile flag checks also need to be done with -std=c++11. # The MITK_CXX11_FLAG variable is also used for external projects # build during the MITK super-build. mitkFunctionCheckCompilerFlags("-std=c++11" MITK_CXX11_FLAG) if(NOT MITK_CXX11_FLAG) # Older gcc compilers use -std=c++0x mitkFunctionCheckCompilerFlags("-std=c++0x" MITK_CXX11_FLAG) endif() #----------------------------------------------------------------------------- # Warn if source or build path is too long #----------------------------------------------------------------------------- if(WIN32) set(_src_dir_length_max 50) set(_bin_dir_length_max 50) if(MITK_USE_SUPERBUILD) set(_src_dir_length_max 34) # _src_dir_length_max - strlen(ep/src/ITK-build) set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build) endif() string(LENGTH "${MITK_SOURCE_DIR}" _src_n) string(LENGTH "${MITK_BINARY_DIR}" _bin_n) # The warnings should be converted to errors if(_src_n GREATER _src_dir_length_max) message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})." "Please move the MITK source code directory to a directory with a shorter path." ) endif() if(_bin_n GREATER _bin_dir_length_max) message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})." "Please move the MITK build directory to a directory with a shorter path." ) endif() endif() #----------------------------------------------------------------------------- # Additional MITK Options (also shown during superbuild) #----------------------------------------------------------------------------- macro(env_option name doc value) set(_value $ENV{${name}}) if("${_value}" STREQUAL "") set(_value ${value}) endif() option(${name} "${doc}" ${_value}) endmacro() # ----------------------------------------- # General build options option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) env_option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) env_option(MITK_BUILD_EXAMPLES "Build the MITK Examples" OFF) option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON) mark_as_advanced(MITK_BUILD_ALL_APPS MITK_ENABLE_PIC_READER ) # ----------------------------------------- # Qt version related variables env_option(MITK_USE_QT "Use Qt library" ON) env_option(MITK_USE_QT_WEBENGINE "Use Qt WebEngine library" ON) if(MITK_USE_QT) set(MITK_QT5_MINIMUM_VERSION 5.6.0) set(MITK_QT5_COMPONENTS Concurrent OpenGL PrintSupport Script Sql Svg Widgets Xml XmlPatterns UiTools Help LinguistTools) if(MITK_USE_QT_WEBENGINE) set(MITK_QT5_COMPONENTS ${MITK_QT5_COMPONENTS} WebEngineWidgets) endif() if(APPLE) set(MITK_QT5_COMPONENTS ${MITK_QT5_COMPONENTS} DBus) endif() find_package(Qt5 ${MITK_QT5_MINIMUM_VERSION} COMPONENTS ${MITK_QT5_COMPONENTS} REQUIRED) if(Qt5_DIR) get_filename_component(_Qt5_DIR "${Qt5_DIR}/../../../" ABSOLUTE) list(FIND CMAKE_PREFIX_PATH "${_Qt5_DIR}" _result) if(_result LESS 0) set(CMAKE_PREFIX_PATH "${_Qt5_DIR};${CMAKE_PREFIX_PATH}" CACHE PATH "" FORCE) endif() endif() elseif(MITK_USE_QT_WEBENGINE) set(MITK_USE_QT_WEBENGINE OFF) endif() # ------------------------------------------------------------------------ # Register external projects which can be build with the MITK superbuild # system. Each mitkFunctionAddExternalProject() call registers an external # project for which a CMakeExternals/.cmake file must exist. The # call also creates a MITK_USE_ variable (appearing in the CMake # UI if the NO_CACHE option is *not* given). # ----------------------------------------- # Optional external projects with no # inter-dependencies set_property(GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS "") mitkFunctionAddExternalProject(NAME Poco ON COMPONENTS Foundation Net Util XML Zip) mitkFunctionAddExternalProject(NAME DCMTK ON DOC "EXPERIMENTAL, superbuild only: Use DCMTK in MITK") mitkFunctionAddExternalProject(NAME OpenIGTLink OFF) mitkFunctionAddExternalProject(NAME tinyxml ON ADVANCED) mitkFunctionAddExternalProject(NAME GDCM ON ADVANCED) mitkFunctionAddExternalProject(NAME GLUT OFF ADVANCED) mitkFunctionAddExternalProject(NAME Raptor2 OFF ADVANCED) mitkFunctionAddExternalProject(NAME Eigen ON ADVANCED DOC "Use the Eigen library") mitkFunctionAddExternalProject(NAME GLEW ON ADVANCED DOC "Use the GLEW library") mitkFunctionAddExternalProject(NAME ANN ON ADVANCED DOC "Use Approximate Nearest Neighbor Library") mitkFunctionAddExternalProject(NAME CppUnit ON ADVANCED DOC "Use CppUnit for unit tests") mitkFunctionAddExternalProject(NAME PCRE OFF ADVANCED NO_PACKAGE) mitkFunctionAddExternalProject(NAME ZLIB OFF ADVANCED NO_PACKAGE NO_CACHE) mitkFunctionAddExternalProject(NAME HDF5 OFF ADVANCED) # ----------------------------------------- # The following external projects must be # ordered according to their # inter-dependencies mitkFunctionAddExternalProject(NAME SWIG OFF ADVANCED NO_PACKAGE DEPENDS PCRE) mitkFunctionAddExternalProject(NAME Python OFF NO_PACKAGE DEPENDS SWIG DOC "Use Python wrapping in MITK") mitkFunctionAddExternalProject(NAME Numpy OFF ADVANCED NO_PACKAGE) mitkFunctionAddExternalProject(NAME OpenCV OFF) mitkFunctionAddExternalProject(NAME Vigra OFF DEPENDS HDF5) # These are "hard" dependencies and always set to ON mitkFunctionAddExternalProject(NAME ITK ON NO_CACHE) mitkFunctionAddExternalProject(NAME VTK ON NO_CACHE) mitkFunctionAddExternalProject(NAME Boost ON NO_CACHE) mitkFunctionAddExternalProject(NAME SimpleITK OFF DEPENDS ITK GDCM SWIG) mitkFunctionAddExternalProject(NAME ACVD OFF DOC "Use Approximated Centroidal Voronoi Diagrams") mitkFunctionAddExternalProject(NAME CTK ON DEPENDS QT DCMTK DOC "Use CTK in MITK") mitkFunctionAddExternalProject(NAME Rasqal OFF DEPENDS Raptor2 PCRE ADVANCED) mitkFunctionAddExternalProject(NAME Redland OFF DEPENDS Rasqal DOC "Use the Redland RDF library") mitkFunctionAddExternalProject(NAME SOFA OFF DEPENDS GLUT Boost DOC "Use Simulation Open Framework Architecture") mitkFunctionAddExternalProject(NAME VMTK OFF DEPENDS ITK VTK) +mitkFunctionAddExternalProject(NAME MatchPoint OFF ADVANCED DEPENDS ITK DOC "Use the MatchPoint translation image registration library") if(MITK_USE_QT) mitkFunctionAddExternalProject(NAME Qwt ON ADVANCED DEPENDS QT) endif() # ----------------------------------------- # Other MITK_USE_* options not related to # external projects build via the # MITK superbuild env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) env_option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF) #----------------------------------------------------------------------------- # Build configurations #----------------------------------------------------------------------------- set(_buildConfigs "Custom") file(GLOB _buildConfigFiles CMake/BuildConfigurations/*.cmake) foreach(_buildConfigFile ${_buildConfigFiles}) get_filename_component(_buildConfigFile ${_buildConfigFile} NAME_WE) list(APPEND _buildConfigs ${_buildConfigFile}) endforeach() set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations") set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS ${_buildConfigs}) mitkFunctionEnableBuildConfiguration() mitkFunctionCreateWhitelistPaths(MITK) mitkFunctionFindWhitelists(MITK) # ----------------------------------------- # Custom dependency logic option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF) set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries") if(MITK_USE_SOFA) # SOFA requires boost system library list(FIND MITK_USE_Boost_LIBRARIES system _result) if(_result LESS 0) message("> Adding 'system' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES system) endif() # SOFA requires boost thread library list(FIND MITK_USE_Boost_LIBRARIES thread _result) if(_result LESS 0) message("> Adding 'thread' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES thread) endif() # Simulation plugin requires boost chrono library list(FIND MITK_USE_Boost_LIBRARIES chrono _result) if(_result LESS 0) message("> Adding 'chrono' to MITK_USE_Boost_LIBRARIES.") list(APPEND MITK_USE_Boost_LIBRARIES chrono) endif() set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "" FORCE) # Allow setting external SOFA plugins directory and SOFA plugins set(MITK_USE_SOFA_PLUGINS_DIR ${MITK_USE_SOFA_PLUGINS_DIR} CACHE PATH "External SOFA plugins directory" FORCE) set(MITK_USE_SOFA_PLUGINS ${MITK_USE_SOFA_PLUGINS} CACHE PATH "List of semicolon-separated plugin names" FORCE) endif() # sanity check for supported Qt version. Only >= 5.3 is supported by CTK/PythonQt if(MITK_USE_QT AND MITK_USE_Python) set(minimum_required_python_qt5_version "5.3.0") find_package(Qt5 COMPONENTS Core REQUIRED) if(${Qt5Core_VERSION_STRING} VERSION_LESS ${minimum_required_python_qt5_version}) message(WARNING "Can't build MITK Python with Qt version < ${minimum_required_python_qt5_version}. Disabling Python support") set(MITK_USE_Python OFF CACHE BOOL "Use python wrapping in MITK" FORCE) endif() endif() # only windows can't build python in debug mode if(MITK_USE_Python AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND WIN32) message(WARNING "Disabling Python support. Building MITK Python in debug mode on Windowsis not supported!") set(MITK_USE_Python OFF CACHE BOOL "Use python wrapping in MITK" FORCE) set(MITK_USE_Numpy OFF CACHE BOOL "Use Numpy" FORCE) set(MITK_USE_SimpleITK OFF CACHE BOOL "Use SimpleITK" FORCE) elseif(MITK_USE_Python) set(MITK_USE_ZLIB ON) if(NOT MITK_USE_Numpy) message("> Forcing MITK_USE_Numpy to ON because of MITK_USE_Python") set(MITK_USE_Numpy ON CACHE BOOL "Use Numpy" FORCE) endif() if(NOT MITK_USE_SimpleITK) message("> Forcing MITK_USE_SimpleITK to ON because of MITK_USE_Python") set(MITK_USE_SimpleITK ON CACHE BOOL "Use SimpleITK" FORCE) endif() option(MITK_USE_SYSTEM_PYTHON "Use the system python runtime" OFF) if(MITK_USE_SYSTEM_PYTHON) find_package(PythonLibs REQUIRED) find_package(PythonInterp REQUIRED) endif() elseif(MITK_USE_Python AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND WIN32) message(WARNING "Disabling Python support. Building MITK Python in debug mode on Windowsis not supported!") set(MITK_USE_Python OFF CACHE BOOL "Use python wrapping in MITK" FORCE) endif() if(BUILD_TESTING AND NOT MITK_USE_CppUnit) message("> Forcing MITK_USE_CppUnit to ON because BUILD_TESTING=ON") set(MITK_USE_CppUnit ON CACHE BOOL "Use CppUnit for unit tests" FORCE) endif() if(MITK_USE_BLUEBERRY) option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) mark_as_advanced(MITK_BUILD_ALL_PLUGINS) if(NOT MITK_USE_CTK) message("> Forcing MITK_USE_CTK to ON because of MITK_USE_BLUEBERRY") set(MITK_USE_CTK ON CACHE BOOL "Use CTK in MITK" FORCE) endif() endif() #----------------------------------------------------------------------------- # Pixel type multiplexing #----------------------------------------------------------------------------- # Customize the default pixel types for multiplex macros set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel, itk::RGBAPixel" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") mark_as_advanced(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS ) # consistency checks if(NOT MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES) set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES) set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES) set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel, itk::RGBAPixel" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) string(REPLACE "," ";" _integral_types ${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}) string(REPLACE "," ";" _floating_types ${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}) foreach(_scalar_type ${_integral_types} ${_floating_types}) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}itk::VariableLengthVector<${_scalar_type}>,") endforeach() string(LENGTH "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" _length) math(EXPR _length "${_length} - 1") string(SUBSTRING "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" 0 ${_length} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES ${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} CACHE STRING "List of vector pixel types used in AccessByItk and InstantiateAccessFunction macros for itk::VectorImage types" FORCE) endif() if(NOT MITK_ACCESSBYITK_DIMENSIONS) set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") endif() #----------------------------------------------------------------------------- # Project.xml #----------------------------------------------------------------------------- # A list of topologically ordered targets set(CTEST_PROJECT_SUBPROJECTS) list(APPEND CTEST_PROJECT_SUBPROJECTS MITK-Core MITK-CoreUI MITK-IGT MITK-ToF MITK-DTI MITK-Registration MITK-Modules # all modules not contained in a specific subproject MITK-Plugins # all plugins not contained in a specific subproject MITK-Examples Unlabeled # special "subproject" catching all unlabeled targets and tests ) # Configure CTestConfigSubProject.cmake that could be used by CTest scripts configure_file(${MITK_SOURCE_DIR}/CTestConfigSubProject.cmake.in ${MITK_BINARY_DIR}/CTestConfigSubProject.cmake) if(CTEST_PROJECT_ADDITIONAL_TARGETS) # those targets will be executed at the end of the ctest driver script # and they also get their own subproject label set(subproject_list "${CTEST_PROJECT_SUBPROJECTS};${CTEST_PROJECT_ADDITIONAL_TARGETS}") else() set(subproject_list "${CTEST_PROJECT_SUBPROJECTS}") endif() # Generate Project.xml file expected by the CTest driver script mitkFunctionGenerateProjectXml(${MITK_BINARY_DIR} MITK "${subproject_list}" ${MITK_USE_SUPERBUILD}) #----------------------------------------------------------------------------- # Superbuild script #----------------------------------------------------------------------------- if(MITK_USE_SUPERBUILD) include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake") # Print configuration summary message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL) return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(WriteBasicConfigVersionFile) include(CheckCXXSourceCompiles) include(GenerateExportHeader) include(mitkFunctionAddCustomModuleTest) include(mitkFunctionCheckModuleDependencies) include(mitkFunctionCompileSnippets) include(mitkFunctionConfigureVisualStudioUserProjectFile) include(mitkFunctionConvertXPSchema) include(mitkFunctionCreateBlueBerryApplication) include(mitkFunctionCreateCommandLineApp) include(mitkFunctionCreateModule) include(mitkFunctionCreatePlugin) include(mitkFunctionCreateProvisioningFile) include(mitkFunctionCreateWindowsBatchScript) include(mitkFunctionGetLibrarySearchPaths) include(mitkFunctionGetVersion) include(mitkFunctionGetVersionDescription) include(mitkFunctionInstallAutoLoadModules) include(mitkFunctionInstallCTKPlugin) include(mitkFunctionInstallProvisioningFiles) include(mitkFunctionInstallThirdPartyCTKPlugins) include(mitkFunctionOrganizeSources) include(mitkFunctionTestPlugin) include(mitkFunctionUseModules) +if( ${MITK_USE_MatchPoint} ) + include(mitkFunctionCreateMatchPointDeployedAlgorithm) +endif() include(mitkMacroConfigureItkPixelTypes) include(mitkMacroCreateExecutable) include(mitkMacroCreateModuleTests) include(mitkMacroGenerateToolsLibrary) include(mitkMacroGetLinuxDistribution) include(mitkMacroGetPMDPlatformString) include(mitkMacroInstall) include(mitkMacroInstallHelperApp) include(mitkMacroInstallTargets) include(mitkMacroMultiplexPicType) # Deprecated include(mitkMacroCreateCTKPlugin) #----------------------------------------------------------------------------- # Global CMake variables #----------------------------------------------------------------------------- # Required and enabled C++11 features for all MITK code. # These are added as PUBLIC compile features to all MITK modules. set(MITK_CXX_FEATURES cxx_auto_type cxx_decltype cxx_enum_forward_declarations cxx_extended_friend_declarations cxx_extern_templates cxx_final cxx_lambdas cxx_local_type_template_args cxx_long_long_type cxx_nullptr cxx_override cxx_range_for cxx_right_angle_brackets cxx_rvalue_references cxx_static_assert cxx_strong_enums cxx_template_template_parameters cxx_trailing_return_types cxx_variadic_macros ) if(NOT DEFINED CMAKE_DEBUG_POSTFIX) # We can't do this yet because the CTK Plugin Framework # cannot cope with a postfix yet. #set(CMAKE_DEBUG_POSTFIX d) endif() #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- set(_default_LIBRARY_output_dir lib) set(_default_RUNTIME_output_dir bin) set(_default_ARCHIVE_output_dir lib) foreach(type LIBRARY RUNTIME ARCHIVE) # Make sure the directory exists if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") endif() if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) else() set(CMAKE_${type}_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${_default_${type}_output_dir}) set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY}) endif() set(CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY} CACHE INTERNAL "Output directory for ${type} files.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- # Look for optional Doxygen package find_package(Doxygen) option(BLUEBERRY_DEBUG_SMARTPOINTER "Enable code for debugging smart pointers" OFF) mark_as_advanced(BLUEBERRY_DEBUG_SMARTPOINTER) # ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and mitkWorkbench option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON) mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW) # TODO: check if necessary option(USE_ITKZLIB "Use the ITK zlib for pic compression." ON) mark_as_advanced(USE_ITKZLIB) if(NOT MITK_FAST_TESTING) if(DEFINED MITK_CTEST_SCRIPT_MODE AND (MITK_CTEST_SCRIPT_MODE STREQUAL "continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "experimental") ) set(MITK_FAST_TESTING 1) endif() endif() if(NOT UNIX AND NOT MINGW) set(MITK_WIN32_FORCE_STATIC "STATIC" CACHE INTERNAL "Use this variable to always build static libraries on non-unix platforms") endif() if(MITK_BUILD_ALL_PLUGINS) set(MITK_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL") endif() # Configure pixel types used for ITK image access multiplexing mitkMacroConfigureItkPixelTypes() # Configure module naming conventions set(MITK_MODULE_NAME_REGEX_MATCH "^[A-Z].*$") set(MITK_MODULE_NAME_REGEX_NOT_MATCH "^[Mm][Ii][Tt][Kk].*$") set(MITK_MODULE_NAME_PREFIX "Mitk") set(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME 1) #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK) mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK) # MITK_VERSION set(MITK_VERSION_STRING "${MITK_VERSION_MAJOR}.${MITK_VERSION_MINOR}.${MITK_VERSION_PATCH}") if(MITK_VERSION_PATCH STREQUAL "99") set(MITK_VERSION_STRING "${MITK_VERSION_STRING}-${MITK_REVISION_SHORTID}") endif() #----------------------------------------------------------------------------- # Installation preparation # # These should be set before any MITK install macros are used #----------------------------------------------------------------------------- # on Mac OSX all BlueBerry plugins get copied into every # application bundle (.app directory) specified here if(MITK_USE_BLUEBERRY AND APPLE) include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) list(GET target_info_list 0 app_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name}) endif() endforeach() endif() #----------------------------------------------------------------------------- # Set coverage Flags #----------------------------------------------------------------------------- if(WITH_COVERAGE) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG") set(COVERAGE_CXX_FLAGS ${coverage_flags}) set(COVERAGE_C_FLAGS ${coverage_flags}) endif() endif() #----------------------------------------------------------------------------- # MITK C/CXX Flags #----------------------------------------------------------------------------- set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}") set(MITK_C_FLAGS_DEBUG ) set(MITK_C_FLAGS_RELEASE ) set(MITK_CXX_FLAGS "${COVERAGE_CXX_FLAGS} ${MITK_CXX11_FLAG}") set(MITK_CXX_FLAGS_DEBUG ) set(MITK_CXX_FLAGS_RELEASE ) set(MITK_EXE_LINKER_FLAGS ) set(MITK_SHARED_LINKER_FLAGS ) find_package(OpenMP) if (OPENMP_FOUND) set(MITK_C_FLAGS "${MITK_C_FLAGS} ${OpenMP_C_FLAGS}") set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() if(WIN32) set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN -DNOMINMAX") mitkFunctionCheckCompilerFlags("/wd4005" MITK_CXX_FLAGS) # warning C4005: macro redefinition mitkFunctionCheckCompilerFlags("/wd4231" MITK_CXX_FLAGS) # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation # the following line should be removed after fixing bug 17637 mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap mitkFunctionCheckCompilerFlags("/wd4180" MITK_CXX_FLAGS) # warning C4180: qualifier applied to function type has no meaning endif() if(NOT MSVC_VERSION) foreach(_flag -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Wno-error=gnu -Wno-error=unknown-pragmas # The strict-overflow warning is generated by ITK template code -Wno-error=strict-overflow -Woverloaded-virtual -Wstrict-null-sentinel #-Wold-style-cast #-Wsign-promo -Wno-array-bounds -fdiagnostics-show-option ) mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS) endforeach() endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS) mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS) endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS) if(MINGW) # suppress warnings about auto imported symbols set(MITK_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import ${MITK_SHARED_LINKER_FLAGS}") endif() set(MITK_CXX_FLAGS_RELEASE "-U_FORTIFY_SOURCES -D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}") endif() set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) #----------------------------------------------------------------------------- # MITK Packages #----------------------------------------------------------------------------- set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends) set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR}) if(NOT MITK_USE_SYSTEM_Boost) set(Boost_NO_SYSTEM_PATHS 1) endif() set(Boost_USE_MULTITHREADED 1) set(Boost_USE_STATIC_LIBS 0) set(Boost_USE_STATIC_RUNTIME 0) set(Boost_ADDITIONAL_VERSIONS "1.60" "1.60.0") # We need this later for a DCMTK workaround set(_dcmtk_dir_orig ${DCMTK_DIR}) # This property is populated at the top half of this file get_property(MITK_EXTERNAL_PROJECTS GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(MITK_USE_${ep} AND _package) if(_components) find_package(${_package} COMPONENTS ${_components} REQUIRED CONFIG) else() # Prefer config mode first because it finds external # Config.cmake files pointed at by _DIR variables. # Otherwise, existing Find.cmake files could fail. # (e.g. in the case of GLEW and the FindGLEW.cmake file shipped # with CMake). find_package(${_package} QUIET CONFIG) string(TOUPPER "${_package}" _package_uc) if(NOT (${_package}_FOUND OR ${_package_uc}_FOUND)) find_package(${_package} REQUIRED) endif() endif() endif() endforeach() # Ensure that the MITK CMake module path comes first set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR} ${CMAKE_MODULE_PATH} ) if(MITK_USE_DCMTK) # Due to the preferred CONFIG mode in find_package calls above, # the DCMTKConfig.cmake file is read, which does not provide useful # package information. We explictly need MODULE mode to find DCMTK. if(${_dcmtk_dir_orig} MATCHES "${MITK_EXTERNAL_PROJECT_PREFIX}.*") # Help our FindDCMTK.cmake script find our super-build DCMTK set(DCMTK_DIR ${MITK_EXTERNAL_PROJECT_PREFIX}) else() # Use the original value set(DCMTK_DIR ${_dcmtk_dir_orig}) endif() find_package(DCMTK REQUIRED MODULE) endif() if(MITK_USE_Python) find_package(PythonLibs REQUIRED) find_package(PythonInterp REQUIRED) if(MITK_USE_Numpy) find_package(Numpy REQUIRED) endif() endif() if(MITK_USE_SOFA) # The SOFAConfig.cmake file does not provide exported targets or # libraries with absolute paths, hence we need to make the link # directories globally available until the SOFAConfig.cmake file # supports a proper mechanism for handling targets. # The same code is needed in MITKConfig.cmake. link_directories(${SOFA_LIBRARY_DIRS}) endif() # Same as SOFA above link_directories(${Boost_LIBRARY_DIRS}) if(MITK_USE_OpenIGTLink) # Same as SOFA above link_directories(${OpenIGTLink_LIBRARY_DIRS}) endif() if(MITK_USE_SimpleITK) link_directories(${SimpleITK_LIBRARY_DIRS}) endif() if(MITK_USE_OpenCL) find_package(OpenCL REQUIRED) endif() # Qt support if(MITK_USE_QT) find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) # at least Core required get_target_property(_qmake_exec Qt5::qmake LOCATION) execute_process(COMMAND ${_qmake_exec} -query QT_INSTALL_BINS RESULT_VARIABLE _result OUTPUT_VARIABLE QT_BINARY_DIR ERROR_VARIABLE _error ) string(STRIP "${QT_BINARY_DIR}" QT_BINARY_DIR) if(_result OR NOT EXISTS "${QT_BINARY_DIR}") message(FATAL_ERROR "Could not determine Qt binary directory: ${_result} ${QT_BINARY_DIR} ${_error}") endif() find_program(QT_HELPGENERATOR_EXECUTABLE NAMES qhelpgenerator qhelpgenerator-qt5 qhelpgenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_COLLECTIONGENERATOR_EXECUTABLE NAMES qcollectiongenerator qcollectiongenerator-qt5 qcollectiongenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_ASSISTANT_EXECUTABLE NAMES assistant assistant-qt5 assistant5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_XMLPATTERNS_EXECUTABLE NAMES xmlpatterns PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) mark_as_advanced(QT_HELPGENERATOR_EXECUTABLE QT_COLLECTIONGENERATOR_EXECUTABLE QT_ASSISTANT_EXECUTABLE QT_XMLPATTERNS_EXECUTABLE ) if(MITK_USE_BLUEBERRY) option(BLUEBERRY_USE_QT_HELP "Enable support for integrating plugin documentation into Qt Help" ${DOXYGEN_FOUND}) mark_as_advanced(BLUEBERRY_USE_QT_HELP) # Sanity checks for in-application BlueBerry plug-in help generation if(BLUEBERRY_USE_QT_HELP) set(_force_blueberry_use_qt_help_to_off 0) if(NOT DOXYGEN_FOUND) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen was not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(DOXYGEN_FOUND AND DOXYGEN_VERSION VERSION_LESS 1.8.7) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen version 1.8.7 or newer not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_HELPGENERATOR_EXECUTABLE) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because QT_HELPGENERATOR_EXECUTABLE is empty.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT MITK_USE_QT_WEBENGINE) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because MITK_USE_QT_WEBENGINE is OFF.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_XMLPATTERNS_EXECUTABLE) message("You have enabled Qt Help support, but QT_XMLPATTERNS_EXECUTABLE is empty") set(_force_blueberry_use_qt_help_to_off 1) endif() if(_force_blueberry_use_qt_help_to_off) set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating plugin documentation into Qt Help" FORCE) endif() endif() if(BLUEBERRY_QT_HELP_REQUIRED AND NOT BLUEBERRY_USE_QT_HELP) message(FATAL_ERROR "BLUEBERRY_USE_QT_HELP is required to be set to ON") endif() endif() endif() #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() include(CTest) mark_as_advanced(TCL_TCLSH DART_ROOT) option(MITK_ENABLE_RENDERING_TESTING OFF "Enable the MITK rendering tests. Requires x-server in Linux.") #Rendering testing does not work for Linux nightlies, thus it is disabled per default #and activated for Mac and Windows. if(WIN32 OR APPLE) set(MITK_ENABLE_RENDERING_TESTING ON) endif() mark_as_advanced( MITK_ENABLE_RENDERING_TESTING ) # Setup file for setting custom ctest vars configure_file( CMake/CTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @ONLY ) # Initial cache for ProjectTemplate and PluginGenerator tests configure_file( CMake/mitkTestInitialCache.txt.in ${MITK_BINARY_DIR}/mitkTestInitialCache.txt @ONLY ) # Configuration for the CMake-generated test driver set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include ") set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " try {") set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " } catch( std::exception & excp ) { fprintf(stderr,\"%s\\n\",excp.what()); return EXIT_FAILURE; } catch( ... ) { printf(\"Exception caught in the test driver\\n\"); return EXIT_FAILURE; } ") set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output") if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR}) file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR}) endif() # Test the external project template if(MITK_USE_BLUEBERRY) include(mitkTestProjectTemplate) endif() # Test the package target include(mitkPackageTest) endif() configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h) #----------------------------------------------------------------------------- # MITK_SUPERBUILD_BINARY_DIR #----------------------------------------------------------------------------- # If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild. # In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR) set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Set C/CXX and linker flags for MITK code #----------------------------------------------------------------------------- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}") #----------------------------------------------------------------------------- # Add custom targets representing CDash subprojects #----------------------------------------------------------------------------- foreach(subproject ${CTEST_PROJECT_SUBPROJECTS}) if(NOT TARGET ${subproject} AND NOT subproject MATCHES "Unlabeled") add_custom_target(${subproject}) endif() endforeach() #----------------------------------------------------------------------------- # Add subdirectories #----------------------------------------------------------------------------- add_subdirectory(Utilities) add_subdirectory(Modules) if(MITK_USE_BLUEBERRY) set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/) set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins) # Plug-in testing (needs some work to be enabled again) if(BUILD_TESTING) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp") if(TARGET CoreApp) get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE) if(APPLE AND _is_macosx_bundle) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp") endif() endif() set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake") mitkFunctionWhitelistPlugins(MITK MITK_PLUGINS) set(mitk_plugins_fullpath "") foreach(mitk_plugin ${MITK_PLUGINS}) list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin}) endforeach() if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake) include(${MITK_PRIVATE_MODULES}/PluginList.cmake) foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS}) list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin}) endforeach() endif() if(MITK_BUILD_EXAMPLES) include("${CMAKE_CURRENT_SOURCE_DIR}/Examples/Plugins/PluginList.cmake") set(mitk_example_plugins_fullpath ) foreach(mitk_example_plugin ${MITK_EXAMPLE_PLUGINS}) list(APPEND mitk_example_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) list(APPEND mitk_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) endforeach() endif() # Specify which plug-ins belong to this project macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin_mitk "^org_mitk_[a-zA-Z0-9_]+$") set(re_ctkplugin_bb "^org_blueberry_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin_mitk re_ctkplugin_bb OUTPUT_VARIABLE ${varname}) endmacro() # Get infos about application directories and build options include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") set(mitk_apps_fullpath ) foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 directory_name) list(GET target_info_list 1 option_name) if(${option_name}) list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${directory_name}^^${option_name}") endif() endforeach() if (mitk_plugins_fullpath) ctkMacroSetupPlugins(${mitk_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) endif() set(MITK_PLUGIN_USE_FILE "${MITK_BINARY_DIR}/MitkPluginUseFile.cmake") if(${PROJECT_NAME}_PLUGIN_LIBRARIES) ctkFunctionGeneratePluginUseFile(${MITK_PLUGIN_USE_FILE}) else() file(REMOVE ${MITK_PLUGIN_USE_FILE}) set(MITK_PLUGIN_USE_FILE ) endif() endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- if(DOXYGEN_FOUND) add_subdirectory(Documentation) endif() #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables # These are the default variables, which can be overwritten ( see below ) include(mitkSetupCPack) set(use_default_config ON) # MITK_APPS is set in Applications/AppList.cmake (included somewhere above # if MITK_USE_BLUEBERRY is set to ON). if(MITK_APPS) set(activated_apps_no 0) list(LENGTH MITK_APPS app_count) # Check how many apps have been enabled # If more than one app has been activated, the we use the # default CPack configuration. Otherwise that apps configuration # will be used, if present. foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) MATH(EXPR activated_apps_no "${activated_apps_no} + 1") endif() endforeach() if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS)) # Corner case if there is only one app in total set(use_project_cpack ON) elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS) # Only one app is enabled (no "build all" flag set) set(use_project_cpack ON) else() # Less or more then one app is enabled set(use_project_cpack OFF) endif() foreach(mitk_app ${MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) list(GET target_info_list 2 executable_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) # check whether application specific configuration files will be used if(use_project_cpack) # use files if they exist if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") endif() if(EXISTS "${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/Applications/${target_dir}/CPackConfig.cmake") configure_file(${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in ${CPACK_PROJECT_CONFIG_FILE} @ONLY) set(use_default_config OFF) endif() endif() # add link to the list list(APPEND CPACK_CREATE_DESKTOP_LINKS "${executable_name}") endif() endforeach() endif() # if no application specific configuration file was used, use default if(use_default_config) configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake") endif() # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- # ---------------- Export targets ----------------- set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake") file(REMOVE ${MITK_EXPORTS_FILE}) set(targets_to_export) get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS) if(module_targets) list(APPEND targets_to_export ${module_targets}) endif() if(MITK_USE_BLUEBERRY) if(MITK_PLUGIN_LIBRARIES) list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES}) endif() endif() export(TARGETS ${targets_to_export} APPEND FILE ${MITK_EXPORTS_FILE}) set(MITK_EXPORTED_TARGET_PROPERTIES ) foreach(target_to_export ${targets_to_export}) get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS) if(autoload_targets) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")") endif() get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY) if(autoload_dir) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")") endif() get_target_property(deprecated_module ${target_to_export} MITK_MODULE_DEPRECATED_SINCE) if(deprecated_module) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_MODULE_DEPRECATED_SINCE \"${deprecated_module}\")") endif() endforeach() # ---------------- External projects ----------------- get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) set(MITK_CONFIG_EXTERNAL_PROJECTS ) #string(REPLACE "^^" ";" _mitk_external_projects ${MITK_EXTERNAL_PROJECTS}) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} set(MITK_USE_${ep} ${MITK_USE_${ep}}) set(MITK_${ep}_DIR \"${${ep}_DIR}\") set(MITK_${ep}_COMPONENTS ${_components}) ") endforeach() foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(_components) set(_components_arg COMPONENTS \${_components}) else() set(_components_arg) endif() if(_package) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} if(MITK_USE_${ep}) set(${ep}_DIR \${MITK_${ep}_DIR}) if(MITK_${ep}_COMPONENTS) mitkMacroFindDependency(${_package} COMPONENTS \${MITK_${ep}_COMPONENTS}) else() mitkMacroFindDependency(${_package}) endif() endif()") endif() endforeach() # ---------------- Tools ----------------- configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY) # ---------------- Configure files ----------------- configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc) set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion) # If we are under Windows, create two batch files which correctly # set up the environment for the application and for Visual Studio if(WIN32) include(mitkFunctionCreateWindowsBatchScript) set(VS_SOLUTION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln") if(MITK_USE_HDF5) list(APPEND MITK_LIBRARY_DIRS ${HDF5_DIR}/install/bin) message(STATUS "MITK-Runtime " ${MITK_RUNTIME_PATH}) endif(MITK_USE_HDF5) foreach(VS_BUILD_TYPE debug release) mitkFunctionCreateWindowsBatchScript("${MITK_SOURCE_DIR}/CMake/StartVS.bat.in" ${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat ${VS_BUILD_TYPE}) endforeach() endif(WIN32) #----------------------------------------------------------------------------- # MITK Applications #----------------------------------------------------------------------------- # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Applications) #----------------------------------------------------------------------------- # MITK Examples #----------------------------------------------------------------------------- if(MITK_BUILD_EXAMPLES) # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Examples) endif() #----------------------------------------------------------------------------- # Print configuration summary #----------------------------------------------------------------------------- message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL ) diff --git a/Modules/MatchPointRegistration/CMakeLists.txt b/Modules/MatchPointRegistration/CMakeLists.txt new file mode 100644 index 0000000000..f9e690d6e0 --- /dev/null +++ b/Modules/MatchPointRegistration/CMakeLists.txt @@ -0,0 +1,15 @@ +MITK_CREATE_MODULE( + INCLUDE_DIRS PUBLIC Rendering Helper + DEPENDS MitkCore MitkSceneSerializationBase + PACKAGE_DEPENDS + PRIVATE ITK VTK + PUBLIC MatchPoint +) + +if( ${MITK_USE_MatchPoint} ) + ADD_SUBDIRECTORY(autoload/IO) + ADD_SUBDIRECTORY(algorithms) + if(BUILD_TESTING) + ADD_SUBDIRECTORY(Testing) + endif(BUILD_TESTING) +endif() diff --git a/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.cpp b/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.cpp new file mode 100644 index 0000000000..3f24fdfad6 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.cpp @@ -0,0 +1,150 @@ +/*=================================================================== + +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 "QmitkAlgorithmListModel.h" + +#include "mapAlgorithmProfileHelper.h" + + + +QmitkAlgorithmListModel:: + QmitkAlgorithmListModel(QObject *parent) : +QAbstractTableModel(parent) +{ + +} + +void + QmitkAlgorithmListModel:: + SetAlgorithms(::map::deployment::DLLDirectoryBrowser::DLLInfoListType algList) +{ + emit beginResetModel(); + + m_AlgList = algList; + + emit endResetModel(); +}; + +int + QmitkAlgorithmListModel:: + rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + { + return 0; + } + + return m_AlgList.size(); +} + +int + QmitkAlgorithmListModel:: + columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return 4; +} + +QVariant + QmitkAlgorithmListModel:: + data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + QVariant result; + + if(index.row()getAlgorithmUID().getName().c_str()); + break; + case 1: + result = QVariant(info->getAlgorithmUID().getNamespace().c_str()); + break; + case 2: + result = QVariant(info->getAlgorithmUID().getVersion().c_str()); + break; + case 3: + std::stringstream descriptionString; + ::map::algorithm::profile::ValueListType keys = ::map::algorithm::profile::getKeywords(info->getAlgorithmProfileStr()); + for (::map::algorithm::profile::ValueListType::const_iterator keyPos = keys.begin(); keyPos!=keys.end();++keyPos) + { + if (keyPos != keys.begin()) + { + descriptionString << "; "; + } + descriptionString << *keyPos; + } + descriptionString << "

"; + result = QVariant(descriptionString.str().c_str()); + break; + } + } + else if (Qt::UserRole == role) + { + result = QVariant(index.row()); + } + + } + + return result; +} + +Qt::ItemFlags + QmitkAlgorithmListModel:: + flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + return flags; +} + +QVariant + QmitkAlgorithmListModel:: + headerData(int section, Qt::Orientation orientation, int role) const +{ + if( (Qt::DisplayRole == role) && + (Qt::Horizontal == orientation)) + { + if (section==0) + { + return QVariant("Name"); + } + else if (section==1) + { + return QVariant("Namespace"); + } + else if (section==2) + { + return QVariant("Version"); + } + else if (section==3) + { + return QVariant("Keywords"); + } + } + return QVariant(); +} diff --git a/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.h b/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.h new file mode 100644 index 0000000000..1ce8e6e76e --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/QmitkAlgorithmListModel.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 QmitkAlgorithmListModel_h +#define QmitkAlgorithmListModel_h + +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" + +// MatchPoint +#include + +/*! + \class QmitkAlgorithmListModel + Model that takes a list of MatchPoint algorithm dll handles and represents it as model in context of the QT view-model-concept. + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MITKMATCHPOINTREGISTRATION_EXPORT QmitkAlgorithmListModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + QmitkAlgorithmListModel(QObject *parent = NULL); + virtual ~QmitkAlgorithmListModel() {}; + + void SetAlgorithms(::map::deployment::DLLDirectoryBrowser::DLLInfoListType algList); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + +private: + + ::map::deployment::DLLDirectoryBrowser::DLLInfoListType m_AlgList; +}; + +#endif // mitkQmitkAlgorithmListModel_h + diff --git a/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.cpp b/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.cpp new file mode 100644 index 0000000000..36e72b2cf6 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.cpp @@ -0,0 +1,286 @@ +/*=================================================================== + +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 NOMINMAX +#define NOMINMAX +#endif + +#include "QmitkMapPropertyDelegate.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QmitkMapPropertyDelegate::QmitkMapPropertyDelegate(QObject * /*parent*/) +{ +} + +void QmitkMapPropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + + QVariant data = index.data(Qt::DisplayRole); + + QString name = data.value(); + + QStyledItemDelegate::paint(painter, option, index); + +} + +QWidget* QmitkMapPropertyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + QString name = index.model()->data(index.model()->index(index.row(), index.column() - 1)).value(); + + if (data.isValid()) + { + + QWidget* editorWidget = NULL; + + if (data.type() == QVariant::Int) + { + QSpinBox* spinBox = new QSpinBox(parent); + spinBox->setSingleStep(1); + spinBox->setMinimum(std::numeric_limits::min()); + spinBox->setMaximum(std::numeric_limits::max()); + editorWidget = spinBox; + } + // see qt documentation. cast is correct, it would be obsolete if we + // store doubles + else if (static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); + spinBox->setDecimals(5); + spinBox->setSingleStep(0.1); + spinBox->setMinimum(std::numeric_limits::min()); + spinBox->setMaximum(std::numeric_limits::max()); + + editorWidget = spinBox; + } + else if (data.type() == QVariant::StringList) + { + QStringList entries = data.value(); + QComboBox* comboBox = new QComboBox(parent); + comboBox->setEditable(false); + comboBox->addItems(entries); + + editorWidget = comboBox; + } + else + { + editorWidget = QStyledItemDelegate::createEditor(parent, option, index); + } + + if (editorWidget) + { + // install event filter + editorWidget->installEventFilter(const_cast(this)); + } + + return editorWidget; + + } + else + return new QLabel(displayData.toString(), parent); + +} + +void QmitkMapPropertyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + + std::cout << "Set EDITOR DATA : " << data.toDouble() << std::endl; + + if (data.isValid()) + { + + + if (data.type() == QVariant::Int) + { + QSpinBox* spinBox = qobject_cast(editor); + spinBox->setValue(data.toInt()); + } + // see qt documentation. cast is correct, it would be obsolete if we + // store doubles + else if (static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = qobject_cast(editor); + spinBox->setValue(data.toDouble()); + + std::cout << "Set EDITOR DATA : " << spinBox->value() << std::endl; + } + + else if (data.type() == QVariant::StringList) + { + QComboBox* comboBox = qobject_cast(editor); + QString displayString = displayData.value(); + comboBox->setCurrentIndex(comboBox->findData(displayString)); + } + + else + return QStyledItemDelegate::setEditorData(editor, index); + } +} + +void QmitkMapPropertyDelegate::setModelData(QWidget *editor, QAbstractItemModel* model + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + + if (data.isValid()) + { + + if (data.type() == QVariant::Color) + { + QWidget *colorBtn = qobject_cast(editor); + QVariant colorVariant; + colorVariant.setValue(colorBtn->palette().color(QPalette::Button)); + model->setData(index, colorVariant); + } + + else if (data.type() == QVariant::Int) + { + QSpinBox* spinBox = qobject_cast(editor); + int intValue = spinBox->value(); + + QVariant intValueVariant; + intValueVariant.setValue(static_cast(intValue)); + model->setData(index, intValueVariant); + } + + else if (static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = qobject_cast(editor); + double doubleValue = spinBox->value(); + + std::cout << "SET MODEL DATA << FLOAT : " << doubleValue << std::endl; + + QVariant doubleValueVariant; + doubleValueVariant.setValue(static_cast(doubleValue)); + std::cout << "SET MODEL DATA << Variant : " << doubleValue << std::endl; + model->setData(index, doubleValueVariant); + } + + else if (data.type() == QVariant::StringList) + { + QString displayData = data.value(); + + QComboBox* comboBox = qobject_cast(editor); + QString comboBoxValue = comboBox->currentText(); + + QVariant comboBoxValueVariant; + comboBoxValueVariant.setValue(comboBoxValue); + model->setData(index, comboBoxValueVariant); + } + + else + QStyledItemDelegate::setModelData(editor, model, index); + } + +} + +void QmitkMapPropertyDelegate::commitAndCloseEditor() +{ + QWidget* editor = 0; + if (QPushButton *pushBtn = qobject_cast(sender())) + { + editor = pushBtn; + } + + if (editor) + { + emit commitData(editor); + emit closeEditor(editor); + } + +} + +void QmitkMapPropertyDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex & /*index*/) const +{ + editor->setGeometry(option.rect); +} + +void QmitkMapPropertyDelegate::ComboBoxCurrentIndexChanged(int /*index*/) +{ + if (QComboBox *comboBox = qobject_cast(sender())) + { + emit commitData(comboBox); + emit closeEditor(comboBox); + } +} + +void QmitkMapPropertyDelegate::SpinBoxValueChanged(const QString& /*value*/) +{ + QAbstractSpinBox *spinBox = 0; + if ((spinBox = qobject_cast(sender())) + || (spinBox = qobject_cast(sender()))) + { + emit commitData(spinBox); + emit closeEditor(spinBox); + } +} + +void QmitkMapPropertyDelegate::showColorDialog() +{ + +} + +bool QmitkMapPropertyDelegate::eventFilter(QObject *o, QEvent *e) +{ + // filter all kind of events on our editor widgets + // when certain events occur, repaint all render windows, because rendering relevant properties might have changed + switch (e->type()) + { + case QEvent::KeyRelease: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::Wheel: + case QEvent::FocusIn: + { + if (QWidget* editor = dynamic_cast(o)) + { + emit commitData(editor); + } + break; + } + default: + { + break; + } + } + + return false; +} diff --git a/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.h b/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.h new file mode 100644 index 0000000000..d6db990788 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/QmitkMapPropertyDelegate.h @@ -0,0 +1,86 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkPropertyDelegate_h +#define QmitkPropertyDelegate_h + + +/// Toolkit includes. +#include +#include "mitkBaseProperty.h" + +//MITK +#include "MitkMatchPointRegistrationExports.h" + + +/** \class QmitkPropertyDelegate + \brief An item delegate for rendering and editing mitk::Properties in a QTableView. + + \see QmitkPropertiesTableModel*/ +class MITKMATCHPOINTREGISTRATION_EXPORT QmitkMapPropertyDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + /// + /// Creates a new PropertyDelegate. + /// + QmitkMapPropertyDelegate(QObject *parent = 0); + + /// + /// Renders a specific property (overwritten from QItemDelegate) + /// + void paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + /// + /// When the user accepts input this func commits the data to the model (overwritten from QItemDelegate) + /// + void setModelData(QWidget *editor, QAbstractItemModel* model + , const QModelIndex &index) const; + + /// + /// \brief Fit an editor to some geometry (overwritten from QItemDelegate) + /// + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + + bool eventFilter(QObject *o, QEvent *e); + + private slots: + /// + /// Invoked when the user accepts editor input, that is when he does not pushes ESC. + /// + void commitAndCloseEditor(); + void showColorDialog(); + void ComboBoxCurrentIndexChanged(int index); + void SpinBoxValueChanged(const QString& value); + +}; + +#endif /* QMITKPROPERTIESTABLEMODEL_H_ */ diff --git a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp new file mode 100644 index 0000000000..f3b2a713e1 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp @@ -0,0 +1,388 @@ +/*=================================================================== + +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 "mitkAlgorithmHelper.h" + +//itk +#include + +// Mitk +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include + +namespace mitk +{ + + MITKAlgorithmHelper::MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm) : + m_AlgorithmBase(algorithm) + { + m_AllowImageCasting = true; + } + + map::core::RegistrationBase::Pointer + MITKAlgorithmHelper:: + GetRegistration() const + { + map::core::RegistrationBase::Pointer spResult; + + unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); + unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); + + if (movingDim != targetDim) + { + mapDefaultExceptionStaticMacro( << + "Error, algorithm instance has unequal dimensionality and is therefore not supported in the current version of MITKAlgorithmHelper."); + } + + if (movingDim > 3) + { + mapDefaultExceptionStaticMacro( << + "Error, algorithm instance has a dimensionality larger than 3 and is therefore not supported in the current version of MITKAlgorithmHelper."); + } + + typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<2, 2> RegistrationAlg2D2DInterface; + typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<3, 3> RegistrationAlg3D3DInterface; + + RegistrationAlg2D2DInterface* pRegAlgorithm2D2D = dynamic_cast + (m_AlgorithmBase.GetPointer()); + RegistrationAlg3D3DInterface* pRegAlgorithm3D3D = dynamic_cast + (m_AlgorithmBase.GetPointer()); + + if (pRegAlgorithm2D2D) + { + spResult = pRegAlgorithm2D2D->getRegistration(); + } + + if (pRegAlgorithm3D3D) + { + spResult = pRegAlgorithm3D3D->getRegistration(); + } + + return spResult; + } + + mitk::MAPRegistrationWrapper::Pointer + MITKAlgorithmHelper:: + GetMITKRegistrationWrapper() const + { + map::core::RegistrationBase::Pointer spInternalResult = GetRegistration(); + mitk::MAPRegistrationWrapper::Pointer spResult = mitk::MAPRegistrationWrapper::New(); + spResult->SetRegistration(spInternalResult); + return spResult; + }; + + + static const mitk::Image* GetDataAsImage(const mitk::BaseData* data) + { + return dynamic_cast(data); + }; + + static const mitk::PointSet* GetDataAsPointSet(const mitk::BaseData* data) + { + return dynamic_cast(data); + }; + + bool + MITKAlgorithmHelper:: + CheckData(const mitk::BaseData* moving, const mitk::BaseData* target, CheckError::Type& error) const + { + if (! m_AlgorithmBase) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined."); + } + + if (! moving) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is NULL."); + } + + if (! target) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is NULL."); + } + + bool result = false; + m_Error = CheckError::unsupportedDataType; + + unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); + unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); + + if (movingDim != targetDim) + { + m_Error = CheckError::wrongDimension; + } + else + { + //First check if data are point sets or images + if (GetDataAsPointSet(target) && GetDataAsPointSet(moving)) + { + typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; + typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface + PointSetRegInterface; + + PointSetRegInterface* pPointSetInterface = dynamic_cast + (m_AlgorithmBase.GetPointer()); + + if (!pPointSetInterface) + { + result = false; + m_Error = CheckError::unsupportedDataType; + } + } + else if (GetDataAsImage(moving) && GetDataAsImage(target)) + { + if (movingDim == 2) + { + AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages, + 2); + } + else if (movingDim == 3) + { + AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages, + 3); + } + else + { + m_Error = CheckError::wrongDimension; + } + + if (m_Error == CheckError::none || (m_AllowImageCasting && m_Error == CheckError::onlyByCasting)) + { + result = true; + } + } + + } + + error = m_Error; + return result; + + }; + + void MITKAlgorithmHelper::SetAllowImageCasting(bool allowCasting) + { + this->m_AllowImageCasting = allowCasting; + }; + + bool MITKAlgorithmHelper::GetAllowImageCasting() const + { + return this->m_AllowImageCasting; + }; + + void MITKAlgorithmHelper::SetData(const mitk::BaseData* moving, const mitk::BaseData* target) + { + if (! m_AlgorithmBase) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined."); + } + + if (! moving) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is NULL."); + } + + if (! target) + { + mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is NULL."); + } + + unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); + unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); + + if (movingDim != targetDim) + { + mapDefaultExceptionStaticMacro( << + "Error, cannot set data. Current version of MITKAlgorithmHelper only supports images/point sets with same dimensionality."); + } + + if (GetDataAsPointSet(target) && GetDataAsPointSet(moving)) + { + typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; + typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface + PointSetRegInterface; + + PointSetRegInterface* pPointSetInterface = dynamic_cast + (m_AlgorithmBase.GetPointer()); + + pPointSetInterface->setMovingPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP( + GetDataAsPointSet(moving)->GetPointSet())); + pPointSetInterface->setTargetPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP( + GetDataAsPointSet(target)->GetPointSet())); + } + else if (GetDataAsImage(moving) && GetDataAsImage(target)) + { + if (movingDim == 2) + { + AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 2); + } + else if (movingDim == 3) + { + AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 3); + } + } + }; + + template + typename TOutImageType::Pointer MITKAlgorithmHelper::CastImage(const TInImageType* input) const + { + typedef itk::CastImageFilter< TInImageType, TOutImageType > CastFilterType; + typename CastFilterType::Pointer spImageCaster = CastFilterType::New(); + + spImageCaster->SetInput(input); + + typename TOutImageType::Pointer spImage = spImageCaster->GetOutput(); + spImageCaster->Update(); + + return spImage; + } + + template + void MITKAlgorithmHelper::DoSetImages(const itk::Image* moving, + const itk::Image* target) + { + typedef itk::Image MovingImageType; + typedef itk::Image TargetImageType; + typedef itk::Image + InternalDefaultMovingImageType; + typedef itk::Image + InternalDefaultTargetImageType; + + typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface + ImageRegInterface; + typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface + DefaultImageRegInterface; + + + ImageRegInterface* pImageInterface = dynamic_cast(m_AlgorithmBase.GetPointer()); + DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast + (m_AlgorithmBase.GetPointer()); + + if (pImageInterface) + { + //just set directly and you are done + + /**@todo the duplication work arround is needed due to a insufficuence + in the AccessTwoImagesFixedDimensionByItk macro. The macro always cast + the passed image into non const (even if tha image was passed as const). + This behavior enforces the unnecessary use of an writeaccessor, which as a consequence + will lead to redundant access exceptions as long as the algorithm exists; + e.g. in the typical scenario with the MatchPoint Plugins*/ + typedef itk::ImageDuplicator< MovingImageType > MovingDuplicatorType; + typedef itk::ImageDuplicator< TargetImageType > TargetDuplicatorType; + typename MovingDuplicatorType::Pointer mDuplicator = MovingDuplicatorType::New(); + mDuplicator->SetInputImage(moving); + mDuplicator->Update(); + + typename TargetDuplicatorType::Pointer tDuplicator = TargetDuplicatorType::New(); + tDuplicator->SetInputImage(target); + tDuplicator->Update(); + + typename MovingImageType::Pointer clonedMoving = mDuplicator->GetOutput(); + typename TargetImageType::Pointer clonedTarget = tDuplicator->GetOutput(); + + pImageInterface->setTargetImage(clonedTarget); + pImageInterface->setMovingImage(clonedMoving); + } + else if (pDefaultImageInterface) + { + //you may convert it to the default image type and use it then + if (! m_AllowImageCasting) + { + mapDefaultExceptionStaticMacro( << + "Error, cannot set images. MITKAlgorithmHelper has to convert them into MatchPoint default images, but is not allowed. Please reconfigure helper."); + } + + typename InternalDefaultTargetImageType::Pointer spCastedTarget = + CastImage(target); + typename InternalDefaultMovingImageType::Pointer spCastedMoving = + CastImage(moving); + pDefaultImageInterface->setTargetImage(spCastedTarget); + pDefaultImageInterface->setMovingImage(spCastedMoving); + } + else + { + mapDefaultExceptionStaticMacro( << "Error, algorithm is not able to use the based images."); + } + } + + template + void MITKAlgorithmHelper::DoCheckImages(const itk::Image* moving, + const itk::Image* target) const + { + typedef itk::Image MovingImageType; + typedef itk::Image TargetImageType; + typedef itk::Image + InternalDefaultMovingImageType; + typedef itk::Image + InternalDefaultTargetImageType; + + typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface + ImageRegInterface; + typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface + DefaultImageRegInterface; + + ImageRegInterface* pImageInterface = dynamic_cast(m_AlgorithmBase.GetPointer()); + DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast + (m_AlgorithmBase.GetPointer()); + + if (pImageInterface) + { + //just set directly and you are done + m_Error = CheckError::none; + } + else if (pDefaultImageInterface) + { + //you may convert it to the default image type and use it then + m_Error = CheckError::onlyByCasting; + } + else + { + m_Error = CheckError::unsupportedDataType; + } + } + + + mapGenerateAlgorithmUIDPolicyMacro(DummyRegIDPolicy, "de.dkfz.dipp", "Identity", "1.0.0", ""); + + mitk::MAPRegistrationWrapper::Pointer GenerateIdentityRegistration3D() + { + typedef map::algorithm::DummyImageRegistrationAlgorithm::InternalImageType, map::core::discrete::Elements<3>::InternalImageType, DummyRegIDPolicy> + DummyRegType; + DummyRegType::Pointer regAlg = DummyRegType::New(); + mitk::MITKAlgorithmHelper helper(regAlg); + + map::core::discrete::Elements<3>::InternalImageType::Pointer dummyImg = + map::core::discrete::Elements<3>::InternalImageType::New(); + dummyImg->Allocate(); + regAlg->setTargetImage(dummyImg); + regAlg->setMovingImage(dummyImg); + + mitk::MAPRegistrationWrapper::Pointer dummyReg = mitk::MAPRegistrationWrapper::New(); + dummyReg->SetRegistration(regAlg->getRegistration()); + + return dummyReg; + } + +} diff --git a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h b/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h new file mode 100644 index 0000000000..3881798f02 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h @@ -0,0 +1,107 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef mitkAlgorithmHelper_h +#define mitkAlgorithmHelper_h + + +//MatchPoint +#include "mapRegistrationAlgorithmBase.h" +#include "mapRegistrationBase.h" + +//MITK +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" +#include "mitkMAPRegistrationWrapper.h" + +namespace mitk +{ + /*! + \brief MITKAlgorithmHelper + \remark Current implementation is not thread-save. Just use one Helper class per registration task. + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + */ + class MITKMATCHPOINTREGISTRATION_EXPORT MITKAlgorithmHelper + { + public: + + MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm = NULL); + + void SetData(const mitk::BaseData* moving, const mitk::BaseData* target); + + void SetAllowImageCasting(bool allowCasting); + bool GetAllowImageCasting() const; + + struct CheckError + { + enum Type + { + none = 0, + onlyByCasting = 1, + wrongDimension = 2, + unsupportedDataType = 3 + }; + }; + + bool CheckData(const mitk::BaseData* moving, const mitk::BaseData* target, + CheckError::Type& error) const; + + map::core::RegistrationBase::Pointer GetRegistration() const; + + mitk::MAPRegistrationWrapper::Pointer GetMITKRegistrationWrapper() const; + + ~MITKAlgorithmHelper() {} + + private: + + MITKAlgorithmHelper& operator = (const MITKAlgorithmHelper&); + MITKAlgorithmHelper(const MITKAlgorithmHelper&); + + /**Internal helper that casts itk images from one pixel type into an other + (used by DoSetImages if the images have the right dimension but wrong type and AllowImageCasting is activated)*/ + template + typename TOutImageType::Pointer CastImage(const TInImageType* input) const; + + /**Internal helper that is used by SetData if the data are images to set them properly.*/ + template + void DoSetImages(const itk::Image* moving, + const itk::Image* target); + + /**Internal helper that is used by SetData if the data are images to check if the image types are supported by the algorithm.*/ + template + void DoCheckImages(const itk::Image* moving, + const itk::Image* target) const; + + map::algorithm::RegistrationAlgorithmBase::Pointer m_AlgorithmBase; + + bool m_AllowImageCasting; + + mutable CheckError::Type m_Error; + }; + + /**Small helper function that generates Identity transforms in 3D.*/ + mitk::MAPRegistrationWrapper::Pointer MITKMATCHPOINTREGISTRATION_EXPORT GenerateIdentityRegistration3D(); + +} + +#endif + diff --git a/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp new file mode 100644 index 0000000000..54fe5d94df --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.cpp @@ -0,0 +1,392 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "mapRegistration.h" + +#include "mitkImageMappingHelper.h" +#include "mitkRegistrationHelper.h" + +template +typename ::itk::InterpolateImageFunction< TImage >::Pointer generateInterpolator(mitk::ImageMappingInterpolator::Type interpolatorType) +{ + typedef ::itk::InterpolateImageFunction< TImage > BaseInterpolatorType; + typename BaseInterpolatorType::Pointer result; + + switch (interpolatorType) + { + case mitk::ImageMappingInterpolator::NearestNeighbor: + { + result = ::itk::NearestNeighborInterpolateImageFunction::New(); + break; + } + case mitk::ImageMappingInterpolator::BSpline_3: + { + typename ::itk::BSplineInterpolateImageFunction::Pointer spInterpolator = ::itk::BSplineInterpolateImageFunction::New(); + spInterpolator->SetSplineOrder(3); + result = spInterpolator; + break; + } + case mitk::ImageMappingInterpolator::WSinc_Hamming: + { + result = ::itk::WindowedSincInterpolateImageFunction::New(); + break; + } + case mitk::ImageMappingInterpolator::WSinc_Welch: + { + result = ::itk::WindowedSincInterpolateImageFunction >::New(); + break; + } + default: + { + result = ::itk::LinearInterpolateImageFunction::New(); + break; + } + + } + + return result; +}; + +template +void doMITKMap(const ::itk::Image* input, mitk::ImageMappingHelper::ResultImageType::Pointer& result, const mitk::ImageMappingHelper::RegistrationType*& registration, + bool throwOnOutOfInputAreaError, const double& paddingValue, const mitk::ImageMappingHelper::ResultImageGeometryType*& resultGeometry, + bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolatorType) +{ + typedef ::map::core::Registration ConcreteRegistrationType; + typedef ::map::core::ImageMappingTask, ::itk::Image > MappingTaskType; + typename MappingTaskType::Pointer spTask = MappingTaskType::New(); + + typedef typename MappingTaskType::ResultImageDescriptorType ResultImageDescriptorType; + typename ResultImageDescriptorType::Pointer resultDescriptor; + + //check if image and result geometry fits the passed registration + ///////////////////////////////////////////////////////////////// + if (registration->getMovingDimensions()!=VImageDimension) + { + map::core::OStringStream str; + str << "Dimension of MITK image ("<getMovingDimensions()<<")."; + throw mitk::AccessByItkException(str.str()); + } + + if (registration->getTargetDimensions()!=VImageDimension) + { + map::core::OStringStream str; + str << "Dimension of MITK image ("<getTargetDimensions()<<")."; + throw mitk::AccessByItkException(str.str()); + } + + const ConcreteRegistrationType* castedReg = dynamic_cast(registration); + + if (registration->getTargetDimensions()==2 && resultGeometry) + { + mitk::ImageMappingHelper::ResultImageGeometryType::BoundsArrayType bounds = resultGeometry->GetBounds(); + + if (bounds[4]!=0 || bounds[5]!=0) + { + //array "bounds" is constructed as [min Dim1, max Dim1, min Dim2, max Dim2, min Dim3, max Dim3] + //therfore [4] and [5] must be 0 + + map::core::OStringStream str; + str << "Dimension of defined result geometry does not equal the target dimension of the registration object ("<getTargetDimensions()<<")."; + throw mitk::AccessByItkException(str.str()); + } + } + + //check/create resultDescriptor + ///////////////////////// + if (resultGeometry) + { + resultDescriptor = ResultImageDescriptorType::New(); + + typename ResultImageDescriptorType::PointType origin; + typename ResultImageDescriptorType::SizeType size; + typename ResultImageDescriptorType::SpacingType fieldSpacing; + typename ResultImageDescriptorType::DirectionType matrix; + + mitk::ImageMappingHelper::ResultImageGeometryType::BoundsArrayType geoBounds = resultGeometry->GetBounds(); + mitk::Vector3D geoSpacing = resultGeometry->GetSpacing(); + mitk::Point3D geoOrigin = resultGeometry->GetOrigin(); + mitk::AffineTransform3D::MatrixType geoMatrix = resultGeometry->GetIndexToWorldTransform()->GetMatrix(); + + for (unsigned int i = 0; i(geoOrigin[i]); + fieldSpacing[i] = static_cast(geoSpacing[i]); + size[i] = static_cast(geoBounds[(2*i)+1]-geoBounds[2*i])*fieldSpacing[i]; + } + + //Matrix extraction + matrix.SetIdentity(); + unsigned int i; + unsigned int j; + + /// \warning 2D MITK images could have a 3D rotation, since they have a 3x3 geometry matrix. + /// If it is only a rotation around the transversal plane normal, it can be express with a 2x2 matrix. + /// In this case, the ITK image conservs this information and is identical to the MITK image! + /// If the MITK image contains any other rotation, the ITK image will have no rotation at all. + /// Spacing is of course conserved in both cases. + + // the following loop devides by spacing now to normalize columns. + // counterpart of InitializeByItk in mitkImage.h line 372 of revision 15092. + + // Check if information is lost + if ( VImageDimension == 2) + { + if ( ( geoMatrix[0][2] != 0) || + ( geoMatrix[1][2] != 0) || + ( geoMatrix[2][0] != 0) || + ( geoMatrix[2][1] != 0) || + (( geoMatrix[2][2] != 1) && ( geoMatrix[2][2] != -1) )) + { + // The 2D MITK image contains 3D rotation information. + // This cannot be expressed in a 2D ITK image, so the ITK image will have no rotation + } + else + { + // The 2D MITK image can be converted to an 2D ITK image without information loss! + for ( i=0; i < 2; ++i) + { + for( j=0; j < 2; ++j ) + { + matrix[i][j] = geoMatrix[i][j]/fieldSpacing[j]; + } + } + } + } + else if (VImageDimension == 3) + { + // Normal 3D image. Conversion possible without problem! + for ( i=0; i < 3; ++i) + { + for( j=0; j < 3; ++j ) + { + matrix[i][j] = geoMatrix[i][j]/fieldSpacing[j]; + } + } + } + else + { + assert(0); + throw mitk::AccessByItkException("Usage of resultGeometry for 2D images is not yet implemented."); + /**@TODO Implement extraction of 2D-Rotation-Matrix out of 3D-Rotation-Matrix + * to cover this case as well. + * matrix = extract2DRotationMatrix(resultGeometry)*/ + } + + resultDescriptor->setOrigin(origin); + resultDescriptor->setSize(size); + resultDescriptor->setSpacing(fieldSpacing); + resultDescriptor->setDirection(matrix); + } + + //do the mapping + ///////////////////////// + typedef ::itk::InterpolateImageFunction< ::itk::Image > BaseInterpolatorType; + typename BaseInterpolatorType::Pointer interpolator = generateInterpolator< ::itk::Image >(interpolatorType); + assert(interpolator.IsNotNull()); + spTask->setImageInterpolator(interpolator); + spTask->setInputImage(input); + spTask->setRegistration(castedReg); + spTask->setResultImageDescriptor(resultDescriptor); + spTask->setThrowOnMappingError(throwOnMappingError); + spTask->setErrorValue(errorValue); + spTask->setThrowOnPaddingError(throwOnOutOfInputAreaError); + spTask->setPaddingValue(paddingValue); + + spTask->execute(); + mitk::CastToMitkImage<>(spTask->getResultImage(),result); +} + +mitk::ImageMappingHelper::ResultImageType::Pointer + mitk::ImageMappingHelper::map(const InputImageType* input, const RegistrationType* registration, + bool throwOnOutOfInputAreaError, const double& paddingValue, const ResultImageGeometryType* resultGeometry, + bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolatorType) +{ + if (!registration) + { + mitkThrow() << "Cannot map image. Passed registration wrapper pointer is NULL."; + } + if (!input) + { + mitkThrow() << "Cannot map image. Passed image pointer is NULL."; + } + + ResultImageType::Pointer result; + + if(input->GetTimeSteps()==1) + { //map the image and done + AccessByItk_n(input, doMITKMap, (result, registration, throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue, interpolatorType)); + } + else + { //map every time step and compose + + mitk::TimeGeometry::ConstPointer timeGeometry = input->GetTimeGeometry(); + mitk::TimeGeometry::Pointer mappedTimeGeometry = timeGeometry->Clone(); + + for (unsigned int i = 0; iGetTimeSteps(); ++i) + { + ResultImageGeometryType::Pointer mappedGeometry = resultGeometry->Clone(); + mappedTimeGeometry->SetTimeStepGeometry(mappedGeometry,i); + } + + result = mitk::Image::New(); + result->Initialize(input->GetPixelType(),*mappedTimeGeometry, 1, input->GetTimeSteps()); + + for (unsigned int i = 0; iGetTimeSteps(); ++i) + { + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(input); + imageTimeSelector->SetTimeNr(i); + imageTimeSelector->UpdateLargestPossibleRegion(); + + InputImageType::Pointer timeStepInput = imageTimeSelector->GetOutput(); + ResultImageType::Pointer timeStepResult; + AccessByItk_n(timeStepInput, doMITKMap, (timeStepResult, registration, throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue, interpolatorType)); + result->SetVolume(timeStepResult->GetVolumeData()->GetData(),i); + } + } + + return result; +} + +mitk::ImageMappingHelper::ResultImageType::Pointer + mitk::ImageMappingHelper::map(const InputImageType* input, const MITKRegistrationType* registration, + bool throwOnOutOfInputAreaError, const double& paddingValue, const ResultImageGeometryType* resultGeometry, + bool throwOnMappingError, const double& errorValue, mitk::ImageMappingInterpolator::Type interpolatorType) +{ + if (!registration) + { + mitkThrow() << "Cannot map image. Passed registration wrapper pointer is NULL."; + } + if (!registration->GetRegistration()) + { + mitkThrow() << "Cannot map image. Passed registration wrapper containes no registration."; + } + if (!input) + { + mitkThrow() << "Cannot map image. Passed image pointer is NULL."; + } + + ResultImageType::Pointer result = map(input, registration->GetRegistration(), throwOnOutOfInputAreaError, paddingValue, resultGeometry, throwOnMappingError, errorValue); + return result; +} + + +mitk::ImageMappingHelper::ResultImageType::Pointer + mitk::ImageMappingHelper:: + refineGeometry(const InputImageType* input, const RegistrationType* registration, + bool throwOnError) +{ + mitk::ImageMappingHelper::ResultImageType::Pointer result = NULL; + + if (!registration) + { + mitkThrow() << "Cannot refine image geometry. Passed registration pointer is NULL."; + } + if (!input) + { + mitkThrow() << "Cannot refine image geometry. Passed image pointer is NULL."; + } + + mitk::MITKRegistrationHelper::Affine3DTransformType::Pointer spTransform = mitk::MITKRegistrationHelper::getAffineMatrix(registration,false); + if(spTransform.IsNull() && throwOnError) + { + mitkThrow() << "Cannot refine image geometry. Registration does not contain a suitable direct mapping kernel (3D affine transformation or compatible required)."; + } + + if(spTransform.IsNotNull()) + { + //copy input image + result = input->Clone(); + + //refine geometries + for(unsigned int i = 0; i < result->GetTimeSteps(); ++i) + { //refine every time step + result->GetGeometry(i)->Compose(spTransform); + } + result->GetTimeGeometry()->Update(); + } + + return result; +} + +mitk::ImageMappingHelper::ResultImageType::Pointer + mitk::ImageMappingHelper:: + refineGeometry(const InputImageType* input, const MITKRegistrationType* registration, + bool throwOnError) +{ + if (!registration) + { + mitkThrow() << "Cannot refine image geometry. Passed registration wrapper pointer is NULL."; + } + if (!registration->GetRegistration()) + { + mitkThrow() << "Cannot refine image geometry. Passed registration wrapper containes no registration."; + } + if (!input) + { + mitkThrow() << "Cannot refine image geometry. Passed image pointer is NULL."; + } + + ResultImageType::Pointer result = refineGeometry(input, registration->GetRegistration(), throwOnError); + return result; +} + +bool + mitk::ImageMappingHelper:: + canRefineGeometry(const RegistrationType* registration) +{ + bool result = true; + + if (!registration) + { + mitkThrow() << "Cannot check refine capability of registration. Passed registration pointer is NULL."; + } + + //if the helper does not return null, we can refine the geometry. + result = mitk::MITKRegistrationHelper::getAffineMatrix(registration,false).IsNotNull(); + + return result; +} + +bool + mitk::ImageMappingHelper:: + canRefineGeometry(const MITKRegistrationType* registration) +{ + if (!registration) + { + mitkThrow() << "Cannot check refine capability of registration. Passed registration wrapper pointer is NULL."; + } + if (!registration->GetRegistration()) + { + mitkThrow() << "Cannot check refine capability of registration. Passed registration wrapper containes no registration."; + } + + return canRefineGeometry(registration->GetRegistration()); +} + diff --git a/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.h b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.h new file mode 100644 index 0000000000..c1bb869af1 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkImageMappingHelper.h @@ -0,0 +1,117 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef MITK_IMAGE_MAPPING_HELPER_H +#define MITK_IMAGE_MAPPING_HELPER_H + +#include "mapImageMappingTask.h" +#include "mapRegistrationBase.h" +#include "mitkImage.h" +#include "mitkGeometry3D.h" + +#include "mitkMAPRegistrationWrapper.h" + +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + struct ImageMappingInterpolator + { + enum Type + { + UserDefined = 0, //< User may specify the interpolator to use + NearestNeighbor = 1, //< use nearest neighbor + Linear = 2, //< use linear + BSpline_3 = 3, //< use a 3rd order spline + WSinc_Hamming = 4, //< use a wsinc with hamming window + WSinc_Welch = 5 //< use a wsinc with welch window + }; + }; + + namespace ImageMappingHelper + { + typedef ::map::core::RegistrationBase RegistrationType; + typedef ::mitk::MAPRegistrationWrapper MITKRegistrationType; + + typedef ::mitk::BaseGeometry ResultImageGeometryType; + typedef ::mitk::Image InputImageType; + typedef ::mitk::Image ResultImageType; + + /**Helper that maps a given input image + * @param input Image that should be mapped. + * @param registration Pointer to the registration instance that should be used for mapping + * @param throwOnOutOfInputAreaError Indicates if mapping should fail with an exception (true), if the input image does not cover the whole requested region to be mapped into the result image. + * @param paddingValue Indicates the value that should be used if an out of input error occurs (and throwOnOutOfInputAreaError is false). + * @param resultGeometry Pointer to the Geometry object that specifies the grid of the result image. If not defined the geometry of the input image will be used. + * @param throwOnMappingError Indicates if mapping should fail with an exception (true), if the registration does not cover/support the whole requested region for mapping into the result image. + * @param errorValue Indicates the value that should be used if an mapping error occurs (and throwOnMappingError is false). + * @param interpolatorType Indicates the type of interpolation strategy that should be used. + * @pre input must be valid + * @pre registration must be valid + * @pre Dimensionality of the registration must match with the input imageinput must be valid + * @remark Depending in the settings of throwOnOutOfInputAreaError and throwOnMappingError it may also throw + * due to inconsistencies in the mapping process. See parameter description. + * @result Pointer to the resulting mapped image.h*/ + MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType* input, const RegistrationType* registration, + bool throwOnOutOfInputAreaError = false, const double& paddingValue = 0, + const ResultImageGeometryType* resultGeometry = NULL, + bool throwOnMappingError = true, const double& errorValue = 0, mitk::ImageMappingInterpolator::Type interpolatorType = mitk::ImageMappingInterpolator::Linear); + + /**Helper that maps a given input image. + * @overload + * @param input Image that should be mapped. + * @param registration Pointer to the registration instance that should be used for mapping + * @param throwOnOutOfInputAreaError Indicates if mapping should fail with an exception (true), if the input image does not cover the whole requested region to be mapped into the result image. + * @param paddingValue Indicates the value that should be used if an out of input error occurs (and throwOnOutOfInputAreaError is false). + * @param resultGeometry Pointer to the Geometry object that specifies the grid of the result image. If not defined the geometry of the input image will be used. + * @param throwOnMappingError Indicates if mapping should fail with an exception (true), if the registration does not cover/support the whole requested region for mapping into the result image. + * @param errorValue Indicates the value that should be used if an mapping error occurs (and throwOnMappingError is false). + * @param interpolatorType Indicates the type of interpolation strategy that should be used. + * @pre input must be valid + * @pre registration must be valid + * @pre Dimensionality of the registration must match with the input imageinput must be valid + * @remark Depending in the settings of throwOnOutOfInputAreaError and throwOnMappingError it may also throw + * due to inconsistencies in the mapping process. See parameter description. + * @result Pointer to the resulting mapped image.h*/ + MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType* input, const MITKRegistrationType* registration, + bool throwOnOutOfInputAreaError = false, const double& paddingValue = 0, + const ResultImageGeometryType* resultGeometry = NULL, + bool throwOnMappingError = true, const double& errorValue = 0, mitk::ImageMappingInterpolator::Type interpolatorType = mitk::ImageMappingInterpolator::Linear); + + /**Method clones the input image and applies the registration by applying it to the Geometry3D of the image. + Thus this method only produces a result if the passed registration has an direct mapping kernel that + can be converted into an affine matrix transformation. + @pre input must point to a valid instance + @pre registration must point to a valid instance + @pre registration must be decomposable into rotation matrix and offset or throwOnError must be false. + @result Pointer to the result image with refined geometry. May be null if the result cannot be + generated (e.g. the registration cannot be transformed in a affine matrix transformation)*/ + MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer refineGeometry(const InputImageType* input, const RegistrationType* registration, bool throwOnError = true); + /**@overload*/ + MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer refineGeometry(const InputImageType* input, const MITKRegistrationType* registration, bool throwOnError = true); + + /**Method allows to pre checks if a registration could be used with refineGeometry. If this method returns true, + * the registration can be used to refine the geometry of images.*/ + MITKMATCHPOINTREGISTRATION_EXPORT bool canRefineGeometry(const RegistrationType* registration); + /**@overload*/ + MITKMATCHPOINTREGISTRATION_EXPORT bool canRefineGeometry(const MITKRegistrationType* registration); + + } + +} + +#endif \ No newline at end of file diff --git a/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.cpp new file mode 100644 index 0000000000..80137f2818 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.cpp @@ -0,0 +1,172 @@ +/*=================================================================== + +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 "mitkMaskedAlgorithmHelper.h" + +#include + +// Mitk +#include + +// MatchPoint +#include "mapMaskedRegistrationAlgorithmInterface.h" +#include + +namespace mitk +{ + + MaskedAlgorithmHelper::MaskedAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm) : m_AlgorithmBase(algorithm) + { + } + + bool + MaskedAlgorithmHelper:: + CheckSupport(const mitk::Image* movingMask, const mitk::Image* targetMask) const + { + if (! m_AlgorithmBase) mapDefaultExceptionStaticMacro(<< "Error, cannot check data. Helper has no algorithm defined."); + + unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); + unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); + + bool result = movingDim == targetDim; + + if ( movingMask) + { + result = result && (movingMask->GetDimension() == movingDim); + + if (movingDim == 2) + { + typedef itk::Image MaskImageType; + mitk::PixelType maskPixelType = mitk::MakePixelType(); + + result = result && (maskPixelType == movingMask->GetPixelType()); + } + else if (movingDim == 3) + { + typedef itk::Image MaskImageType; + mitk::PixelType maskPixelType = mitk::MakePixelType(); + + result = result && (maskPixelType == movingMask->GetPixelType()); + } + } + + if ( targetMask) + { + result = result && (targetMask->GetDimension() == targetDim); + + if (movingDim == 2) + { + typedef itk::Image MaskImageType; + mitk::PixelType maskPixelType = mitk::MakePixelType(); + + result = result && (maskPixelType == targetMask->GetPixelType()); + } + else if (movingDim == 3) + { + typedef itk::Image MaskImageType; + mitk::PixelType maskPixelType = mitk::MakePixelType(); + + result = result && (maskPixelType == targetMask->GetPixelType()); + } + } + + if (movingDim == 2) + { + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<2, 2> MaskedInterface; + const MaskedInterface* pMaskedReg = dynamic_cast(m_AlgorithmBase.GetPointer()); + + result = result && pMaskedReg; + } + else if (movingDim == 3) + { + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskedInterface; + const MaskedInterface* pMaskedReg = dynamic_cast(m_AlgorithmBase.GetPointer()); + + result = result && pMaskedReg; + } + else + { + result = false; + } + + return result; + }; + + bool MaskedAlgorithmHelper::SetMasks(const mitk::Image* movingMask, const mitk::Image* targetMask) + { + if (! m_AlgorithmBase) mapDefaultExceptionStaticMacro(<< "Error, cannot set data. Helper has no algorithm defined."); + + if (! CheckSupport(movingMask, targetMask)) return false; + + unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); + unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); + + if (movingDim!=targetDim) return false; + + if (movingDim == 2) + { + return DoSetMasks<2,2>(movingMask, targetMask); + } + else if (movingDim == 3) + { + return DoSetMasks<3,3>(movingMask, targetMask); + } + return false; + }; + + template + bool MaskedAlgorithmHelper::DoSetMasks(const mitk::Image* movingMask, const mitk::Image* targetMask) + { + typedef itk::SpatialObject MovingSpatialType; + typedef itk::SpatialObject TargetSpatialType; + + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface MaskedRegInterface; + MaskedRegInterface* pAlg = dynamic_cast(m_AlgorithmBase.GetPointer()); + + if (!pAlg) return false; + + if (movingMask) + { + AccessFixedTypeByItk(movingMask, DoConvertMask, (MaskPixelType), (VImageDimension1)); + typename MovingSpatialType::Pointer movingSpatial = dynamic_cast(m_convertResult.GetPointer()); + if (! movingSpatial) mapDefaultExceptionStaticMacro(<< "Error, cannot convert moving mask."); + pAlg->setMovingMask(movingSpatial); + } + + if (targetMask) + { + AccessFixedTypeByItk(targetMask, DoConvertMask, (MaskPixelType), (VImageDimension2)); + typename TargetSpatialType::Pointer targetSpatial = dynamic_cast(m_convertResult.GetPointer()); + if (! targetSpatial) mapDefaultExceptionStaticMacro(<< "Error, cannot convert moving mask."); + pAlg->setTargetMask(targetSpatial); + } + + return true; + } + + template + void MaskedAlgorithmHelper::DoConvertMask(const itk::Image* mask) + { + typedef itk::Image ImageType; + typedef itk::ImageMaskSpatialObject SpatialType; + + typename SpatialType::Pointer spatial = SpatialType::New(); + spatial->SetImage(mask); + + m_convertResult = spatial.GetPointer(); + } + +} diff --git a/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.h b/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.h new file mode 100644 index 0000000000..54c4a56091 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkMaskedAlgorithmHelper.h @@ -0,0 +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 mitkMaskedAlgorithmHelper_h +#define mitkMaskedAlgorithmHelper_h + + +//MatchPoint +#include "mapRegistrationAlgorithmBase.h" + +//MITK +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + /*! + \brief MaskedAlgorithmHelper + Helper class as an easy bridge to set mitk images as masks for registration algorithms. It is assumed that the + Image indicates the mask by pixel values != 0. + \remark Currently only 2D-2D and 3D-3D algorithms are supported. + \remark Currently only masks with pixel type unsigned char (default mitk segmentation images) are supported. + \remark Current implementation is not thread-save. Just use one Helper class per registration task. + */ + class MITKMATCHPOINTREGISTRATION_EXPORT MaskedAlgorithmHelper + { + public: + + MaskedAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm = NULL); + + /** Set one or both masks to an algorithm. + * If the algorithm does not support masks it will be ignored. + * @remark Set a mask to NULL if you don't want to set it. + * @return Indicates if the masks could be set/was supported by algorithm.*/ + bool SetMasks(const mitk::Image* movingMask, const mitk::Image* targetMask); + + /** Checks if the algorithm supports masks of the passed type.*/ + bool CheckSupport(const mitk::Image* movingMask, const mitk::Image* targetMask) const; + + ~MaskedAlgorithmHelper() {} + + private: + typedef unsigned char MaskPixelType; + + MaskedAlgorithmHelper& operator = (const MaskedAlgorithmHelper&); + MaskedAlgorithmHelper(const MaskedAlgorithmHelper&); + + /**Internal helper that is used by SetMasks if the data are images to set them properly.*/ + template + bool DoSetMasks(const mitk::Image* movingMask, const mitk::Image* targetMask); + + /**Internal helper that is used by SetData if the data are images to set them properly.*/ + template + void DoConvertMask(const itk::Image* mask); + /**Helper member that containes the result of the last call of DoConvertMask().*/ + itk::DataObject::Pointer m_convertResult; + + map::algorithm::RegistrationAlgorithmBase::Pointer m_AlgorithmBase; + }; + +} + +#endif + diff --git a/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.cpp new file mode 100644 index 0000000000..f2a1fb5564 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.cpp @@ -0,0 +1,148 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mapRegistration.h" + +#include "mitkPointSetMappingHelper.h" +#include "mitkRegistrationHelper.h" + + +#include "mapPointSetMappingTask.h" + +::map::core::continuous::Elements<3>::InternalPointSetType::Pointer mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP(const mitk::PointSet::DataType* mitkSet) +{ + if (! mitkSet) mapDefaultExceptionStaticMacro(<< "Error, cannot convert point set. Passed mitk point set is null."); + + ::map::core::continuous::Elements<3>::InternalPointSetType::Pointer mapSet = ::map::core::continuous::Elements<3>::InternalPointSetType::New(); + ::map::core::continuous::Elements<3>::InternalPointSetType::PointsContainer::Pointer mapContainer = ::map::core::continuous::Elements<3>::InternalPointSetType::PointsContainer::New(); + ::map::core::continuous::Elements<3>::InternalPointSetType::PointDataContainer::Pointer mapDataContainer = ::map::core::continuous::Elements<3>::InternalPointSetType::PointDataContainer::New(); + mapSet->SetPoints(mapContainer); + mapSet->SetPointData(mapDataContainer); + + unsigned int pointCount = mitkSet->GetNumberOfPoints(); + + for (unsigned int pointId = 0; pointId < pointCount; ++pointId) + { + mapSet->SetPoint(pointId, mitkSet->GetPoint(pointId)); + + mitk::PointSet::PointDataType data; + if (mitkSet->GetPointData(pointId,&data)) + { + mapSet->SetPointData(pointId,data.id); + } + } + + return mapSet; +} + +::mitk::PointSet::Pointer + mitk::PointSetMappingHelper::map(const ::mitk::PointSet* input, const mitk::PointSetMappingHelper::RegistrationType* registration, int timeStep, + bool throwOnMappingError, const ::mitk::PointSet::PointDataType& errorPointValue) +{ + if (!registration) + { + mitkThrow() << "Cannot map point set. Passed registration wrapper pointer is NULL."; + } + if (!input) + { + mitkThrow() << "Cannot map point set. Passed point set pointer is NULL."; + } + if (input->GetTimeSteps()<=timeStep && timeStep>=0) + { + mitkThrow() << "Cannot set point set. Selected time step is larger then mitk point set. MITK time step count: "<GetTimeSteps()<<"; selected time step: "<Clone(); + + typedef ::map::core::continuous::Elements<3>::InternalPointSetType MAPPointSetType; + typedef ::map::core::Registration<3,3> ConcreteRegistrationType; + const ConcreteRegistrationType* castedReg = dynamic_cast(registration); + if (!castedReg) + { + mitkThrow() <<"Moving and/or fixed dimension of the registration is not 3. Cannot map point 3D set."; + } + + typedef ::map::core::PointSetMappingTask MappingTaskType; + MappingTaskType::ErrorPointValueType internalErrorValue = itk::NumericTraits::NonpositiveMin(); + MappingTaskType::Pointer spTask = MappingTaskType::New(); + spTask->setRegistration(castedReg); + spTask->setThrowOnMappingError(throwOnMappingError); + spTask->setErrorPointValue(internalErrorValue); + + unsigned int timePos = timeStep; + unsigned int timeEndPos = timeStep+1; + if (timeStep < 0) + { + timePos = 0; + timeEndPos = input->GetTimeSteps(); + } + + while (timePosGetPointSet(timePos)); + spTask->setInputPointSet(inputTempSet); + spTask->execute(); + + MAPPointSetType::Pointer mappedSet = spTask->getResultPointSet(); + + unsigned int pointCount = input->GetSize(timePos); + + for (unsigned int pointId = 0; pointId < pointCount; ++pointId) + { + result->SetPoint(pointId, mappedSet->GetPoint(pointId), timePos); + bool invalid = true; + MAPPointSetType::PixelType mappedData; + if (mappedSet->GetPointData(pointId,&mappedData)) + { + invalid = mappedData == internalErrorValue; + } + + if (invalid) + { + result->GetPointSet(timePos)->GetPointData()->SetElement(pointId,errorPointValue); + } + else + { + result->GetPointSet(timePos)->GetPointData()->SetElement(pointId,input->GetPointSet(timePos)->GetPointData()->GetElement(pointId)); + } + } + + ++timePos; + } + + return result; +} + +::mitk::PointSet::Pointer + mitk::PointSetMappingHelper::map(const ::mitk::PointSet* input, const MITKRegistrationType* registration, int timeStep, + bool throwOnMappingError, const ::mitk::PointSet::PointDataType& errorPointValue) +{ + if (!registration) + { + mitkThrow() << "Cannot map point set. Passed registration wrapper pointer is NULL."; + } + if (!registration->GetRegistration()) + { + mitkThrow() << "Cannot map point set. Passed registration wrapper containes no registration."; + } + if (!input) + { + mitkThrow() << "Cannot map point set. Passed point set pointer is NULL."; + } + + ::mitk::PointSet::Pointer result = map(input, registration->GetRegistration(), timeStep, throwOnMappingError, errorPointValue); + return result; +} diff --git a/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.h b/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.h new file mode 100644 index 0000000000..b12df31d4e --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkPointSetMappingHelper.h @@ -0,0 +1,64 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef MITK_POINTSET_MAPPING_HELPER_H +#define MITK_POINTSET_MAPPING_HELPER_H + +#include "mapRegistrationBase.h" +#include + +#include "mitkMAPRegistrationWrapper.h" + +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + + namespace PointSetMappingHelper + { + typedef ::map::core::RegistrationBase RegistrationType; + typedef ::mitk::MAPRegistrationWrapper MITKRegistrationType; + + /**Helper that converts the data of an mitk point set into the default point set type of matchpoint.*/ + MITKMATCHPOINTREGISTRATION_EXPORT ::map::core::continuous::Elements<3>::InternalPointSetType::Pointer ConvertPointSetMITKtoMAP(const mitk::PointSet::DataType* mitkSet); + + /**Helper that maps a given input point set + * @param input Point set that should be mapped. + * @param registration Pointer to the registration instance that should be used for mapping + * @param timeStep Indicates which time step of the point set should be mapped (the rest will just be copied). -1 (default) indicates that all time steps should be mapped. + * @param throwOnMappingError Indicates if mapping should fail with an exception (true), if the registration does not cover/support the whole requested region for mapping into the result image. + * if set to false, points that cause an mapping error will be transfered without mapping but get the passed errorPointValue as data to indicate unmappable points; + * @param errorPointValue Indicates the point data that should be used if an mapping error occurs (and throwOnMappingError is false). + * @pre input must be valid + * @pre registration must be valid + * @pre timeStep must be a valid time step of input or -1 + * @pre Dimensionality of the registration must match with the input imageinput must be valid + * @remark Depending in the settings of throwOnMappingError it may also throw + * due to inconsistencies in the mapping process. See parameter description. + * @result Pointer to the resulting mapped point set*/ + MITKMATCHPOINTREGISTRATION_EXPORT ::mitk::PointSet::Pointer map(const ::mitk::PointSet* input, const RegistrationType* registration, int timeStep = -1, + bool throwOnMappingError = true, const ::mitk::PointSet::PointDataType& errorPointValue = ::mitk::PointSet::PointDataType()); + + /**Helper that maps a given input point set + * @overload*/ + MITKMATCHPOINTREGISTRATION_EXPORT ::mitk::PointSet::Pointer map(const ::mitk::PointSet* input, const MITKRegistrationType* registration, int timeStep = -1, + bool throwOnMappingError = true, const ::mitk::PointSet::PointDataType& errorPointValue = ::mitk::PointSet::PointDataType()); + } + +} + +#endif \ No newline at end of file diff --git a/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.cpp b/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.cpp new file mode 100644 index 0000000000..c139aa4d4d --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.cpp @@ -0,0 +1,341 @@ +/*=================================================================== + +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 "mitkQMAPAlgorithmModel.h" + +#include "mapMetaProperty.h" + +namespace mitk +{ + +QMAPAlgorithmModel:: +QMAPAlgorithmModel(QObject *parent) : + QAbstractTableModel(parent), + m_pMetaInterface(NULL) +{ + +} + +void +QMAPAlgorithmModel:: +SetAlgorithm(map::algorithm::RegistrationAlgorithmBase *pAlgorithm) +{ + this->SetAlgorithm(dynamic_cast(pAlgorithm)); +}; + +void +QMAPAlgorithmModel:: +SetAlgorithm(map::algorithm::facet::MetaPropertyAlgorithmInterface *pMetaInterface) +{ + emit beginResetModel(); + + m_pMetaInterface = pMetaInterface; + this->UpdateMetaProperties(); + + emit endResetModel(); +}; + +int +QMAPAlgorithmModel:: +rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + { + return 0; + } + + return m_MetaProperties.size(); +} + +int +QMAPAlgorithmModel:: +columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return 2; +} + +QVariant +QMAPAlgorithmModel:: +data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(!m_pMetaInterface) + { + return QVariant(); + } + + QVariant result; + + if(index.row()getName().c_str()); + } + break; + case 1: + if (Qt::DisplayRole == role && !pInfo->isReadable()) + { + result = QVariant("value is not accessible"); + } + else if (pInfo->isReadable() && (Qt::DisplayRole == role || (Qt::EditRole == role && pInfo->isWritable()))) + { //should also be readable to be sensible editable in the GUI + result = GetPropertyValue(pInfo,role); + } + break; + } + } + + return result; +} + +Qt::ItemFlags +QMAPAlgorithmModel:: +flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if(index.row()isWritable()) + { + flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + } + } + } + + return flags; +} + +QVariant +QMAPAlgorithmModel:: +headerData(int section, Qt::Orientation orientation, int role) const +{ + if( (Qt::DisplayRole == role) && + (Qt::Horizontal == orientation)) + { + if (section==0) + { + return QVariant("Property"); + } + else if (section==1) + { + return QVariant("Value"); + } + } + return QVariant(); +} + +bool +QMAPAlgorithmModel:: +setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid() || (m_MetaProperties.size() <= index.row()) || (1 != index.column())) + { + return false; + } + + if(Qt::EditRole == role) + { + map::algorithm::MetaPropertyInfo* pInfo = m_MetaProperties[index.row()]; + + bool result = SetPropertyValue(pInfo,value); + + if (result) + { + emit beginResetModel(); + this->UpdateMetaProperties(); + emit endResetModel(); + } + + return result; + } + + return false; +}; + + +void +QMAPAlgorithmModel:: +UpdateMetaProperties() const +{ + if(m_pMetaInterface) + { + m_MetaProperties = m_pMetaInterface->getPropertyInfos(); + } + else + { + m_MetaProperties.clear(); + } +} + +QVariant +QMAPAlgorithmModel:: +GetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, int role) const +{ + if(!m_pMetaInterface) + { + return QVariant(); + } + + map::algorithm::facet::MetaPropertyAlgorithmInterface::MetaPropertyPointer prop = m_pMetaInterface->getProperty(pInfo); + + if(!prop) + { + return QVariant(); + } + + QVariant result; + + if (role == Qt::DisplayRole) + { + result = QVariant(QString("Error. Cannot unwrap MetaProperty. Name: ")+QString::fromStdString(pInfo->getName())); + } + + if (prop->getMetaPropertyTypeInfo()==typeid(bool)) + { + bool val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(int)) + { + int val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(unsigned int)) + { + unsigned int val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(long)) + { + long val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(qlonglong(val)); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(unsigned long)) + { + unsigned long val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(qulonglong(val)); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(float)) + { + float val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(double)) + { + double val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(map::core::String)) + { + map::core::String val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(QString::fromStdString(val)); + } + } + else + { + if (role == Qt::DisplayRole) + { + result = QVariant(QString("Error. Cannot offer MetaProperty because of unsupported type. Property name: ")+QString::fromStdString(pInfo->getName())+QString("; type name: ")+QString(prop->getMetaPropertyTypeName())); + } + } + return result; +}; + +template +bool +QMAPAlgorithmModel:: +CheckCastAndSetProp(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value) +{ + bool result = false; + if (pInfo->getTypeInfo()==typeid(TValueType) && value.canConvert()) + { + /**@TODO: Not save, because canConvert may say true but the actual value is not really convertible (e.g. string to int for the value "a")*/ + TValueType val = value.value(); + map::core::MetaPropertyBase::Pointer spMetaProp = map::core::MetaProperty::New(val).GetPointer(); + + result = m_pMetaInterface->setProperty(pInfo,spMetaProp); + } + return result; +}; + +bool +QMAPAlgorithmModel:: +SetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value) +{ + if(!m_pMetaInterface) + { + return false; + } + + bool result = CheckCastAndSetProp(pInfo,value); + + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result && pInfo->getTypeInfo()==typeid(map::core::String)) + { + map::core::String val = value.toString().toStdString(); + map::core::MetaPropertyBase::Pointer spMetaProp = map::core::MetaProperty::New(val).GetPointer(); + + result = m_pMetaInterface->setProperty(pInfo,spMetaProp); + }; + + return result; +}; + +} diff --git a/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.h b/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.h new file mode 100644 index 0000000000..22ce639e56 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkQMAPAlgorithmModel.h @@ -0,0 +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 mitkQMAPAlgorithmModel_h +#define mitkQMAPAlgorithmModel_h + +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" + +// MatchPoint +#include +#include + +namespace mitk +{ +/*! + \class QMAPAlgorithmModel + Helper class that implements a model to handle the MetaProperty interface of a MatchPoint algorithm + in contect of the QT view-model-concept. A algorithm can be set as data source for the model. + The model retrieves all information through the MetaPropertyInterface. Changes in the view will + be propagated by the model into the algorithm. + \remarks The model only keep a simple pointer to the MetaPropertyInterface of the algorithm. + You have to ensure to reset the algorithm if the pointer goes invalid. + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MITKMATCHPOINTREGISTRATION_EXPORT QMAPAlgorithmModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + QMAPAlgorithmModel(QObject *parent = NULL); + virtual ~QMAPAlgorithmModel() {}; + + void SetAlgorithm(map::algorithm::RegistrationAlgorithmBase *pAlgorithm); + void SetAlgorithm(map::algorithm::facet::MetaPropertyAlgorithmInterface *pMetaInterface); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + +private: + void UpdateMetaProperties() const ; + + /** Method uses m_pMetaInterface to retrieve the MetaProperty and unwraps it into an + * suitable QVariant depending on the passed QT role. If the MetaProperty type is not supported, the QVariant is invalid. + */ + QVariant GetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, int role) const; + + template bool CheckCastAndSetProp(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value); + + bool SetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value); + + map::algorithm::facet::MetaPropertyAlgorithmInterface *m_pMetaInterface; + mutable map::algorithm::facet::MetaPropertyAlgorithmInterface::MetaPropertyVectorType m_MetaProperties; +}; + +}; + +#endif // mitkQMAPAlgorithmModel_h + diff --git a/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.cpp new file mode 100644 index 0000000000..fea344ebee --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.cpp @@ -0,0 +1,138 @@ +/*=================================================================== + +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 "mitkRegistrationHelper.h" + +//MatchPoint +#include "mapRegistrationKernel.h" + +namespace mitk +{ + + MITKRegistrationHelper::Affine3DTransformType::Pointer + MITKRegistrationHelper:: + getAffineMatrix(const mitk::MAPRegistrationWrapper* wrapper, bool inverseKernel) + { + Affine3DTransformType::Pointer result = NULL; + + if (wrapper) + { + result = getAffineMatrix(wrapper->GetRegistration(), inverseKernel); + } + return result; + } + + MITKRegistrationHelper::Affine3DTransformType::Pointer + MITKRegistrationHelper:: + getAffineMatrix(const RegistrationBaseType* registration, bool inverseKernel) + { + Affine3DTransformType::Pointer result = NULL; + + if (registration && is3D(registration)) + { + const Registration3DType* pReg = dynamic_cast(registration); + if (pReg) + { + if (inverseKernel) + { + result = getAffineMatrix(pReg->getInverseMapping()); + } + else + { + result = getAffineMatrix(pReg->getDirectMapping()); + } + } + } + return result; + } + + + MITKRegistrationHelper::Affine3DTransformType::Pointer MITKRegistrationHelper::getAffineMatrix(const RegistrationKernel3DBase& kernel) + { + Affine3DTransformType::Pointer result = NULL; + + typedef ::map::core::RegistrationKernel<3,3> KernelType; + + const KernelType* pModelKernel = dynamic_cast(&kernel); + + if (pModelKernel) + { + + KernelType::TransformType::MatrixType matrix; + KernelType::TransformType::OutputVectorType offset; + + if(pModelKernel->getAffineMatrixDecomposition(matrix,offset)) + { + result = Affine3DTransformType::New(); + Affine3DTransformType::MatrixType resultMatrix; + Affine3DTransformType::OffsetType resultOffset; + + /**@TODO If MatchPoint and MITK get same scalar + values the casting of matrix and offset values is + obsolete and should be removed.*/ + //The conversion of matrix and offset is needed + //because mitk uses float and MatchPoint currently + //double as scalar value. + for (unsigned int i=0; i(matrix.GetVnlMatrix().begin()[i]); + } + resultOffset.CastFrom(offset); //needed because mitk uses float and MatchPoint currently double as scalar value + + result->SetMatrix(resultMatrix); + result->SetOffset(resultOffset); + } + } + return result; + } + + bool MITKRegistrationHelper::is3D(const mitk::MAPRegistrationWrapper* wrapper) + { + bool result = false; + + if (wrapper) + { + result = wrapper->GetMovingDimensions()==3 && wrapper->GetTargetDimensions()==3; + } + return result; + } + + bool MITKRegistrationHelper::is3D(const RegistrationBaseType* reBase) + { + bool result = false; + + if (reBase) + { + result = reBase->getMovingDimensions()==3 && reBase->getTargetDimensions()==3; + } + return result; + } + + bool MITKRegistrationHelper::IsRegNode(const mitk::DataNode* node) + { + if (!node) return false; + + mitk::BaseData* data = node->GetData(); + + if (data != NULL) + { + return std::string("MAPRegistrationWrapper").compare(data->GetNameOfClass()) == 0; + } + + return false; + } +} diff --git a/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.h b/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.h new file mode 100644 index 0000000000..296b4c0d53 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkRegistrationHelper.h @@ -0,0 +1,82 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _mitkRegistrationHelper_h +#define _mitkRegistrationHelper_h + +//ITK +#include "itkScalableAffineTransform.h" + +//MatchPoint +#include "mapRegistrationAlgorithmBase.h" +#include "mapRegistration.h" + +//MITK +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" +#include "mitkMAPRegistrationWrapper.h" + +namespace mitk +{ +/*! + \brief MITKRegistrationHelper + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MITKMATCHPOINTREGISTRATION_EXPORT MITKRegistrationHelper +{ +public: + + typedef ::itk::ScalableAffineTransform< ::mitk::ScalarType,3 > Affine3DTransformType; + typedef ::map::core::Registration<3,3> Registration3DType; + typedef ::map::core::RegistrationBase RegistrationBaseType; + + /** Extracts the affine transformation, if possible, of the selected kernel. + @param wrapper Pointer to the registration that is target of the extraction + @param inverseKernel Indicates from which kernel the matrix should be extract. True: inverse kernel, False: direct kernel. + @return Pointer to the extracted transform. If it is not possible to convert the kernel into an affine transform a null pointer is returned. + @pre wrapper must point to a valid instance. + @pre wrapper must be a 3D-3D registration.*/ + static Affine3DTransformType::Pointer getAffineMatrix(const mitk::MAPRegistrationWrapper* wrapper, bool inverseKernel); + static Affine3DTransformType::Pointer getAffineMatrix(const RegistrationBaseType* registration, bool inverseKernel); + + static bool is3D(const mitk::MAPRegistrationWrapper* wrapper); + static bool is3D(const RegistrationBaseType* regBase); + + /** Checks if the passed Node contains a MatchPoint registration + @param Pointer to the node to be checked.* + @return true: node contains a MAPRegistrationWrapper. false: "node" does not point to a valid instance or does not contain + a registration wrapper.*/; + static bool IsRegNode(const mitk::DataNode* node); + +private: + typedef ::map::core::Registration<3,3>::DirectMappingType RegistrationKernel3DBase; + static Affine3DTransformType::Pointer getAffineMatrix(const RegistrationKernel3DBase& kernel); + + MITKRegistrationHelper(); + ~MITKRegistrationHelper(); + MITKRegistrationHelper& operator = (const MITKRegistrationHelper&); + MITKRegistrationHelper(const MITKRegistrationHelper&); + +}; + +} + +#endif + diff --git a/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.cpp new file mode 100644 index 0000000000..fcf8b0a2db --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.cpp @@ -0,0 +1,81 @@ +/*=================================================================== + +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 "mitkResultNodeGenerationHelper.h" + +#include +#include +#include + +mitk::DataNode::Pointer + mitk::generateRegistrationResultNode(const std::string& nodeName, mitk::MAPRegistrationWrapper::Pointer resultReg, const std::string& algorithmUID, const std::string& movingNodeUID, const std::string& targetNodeUID) +{ + if (resultReg.IsNull()) + { + mitkThrow() << "Cannot generate registration result node. Passed registration wrapper points to NULL."; + } + + mitk::DataNode::Pointer m_spRegNode = mitk::DataNode::New(); + m_spRegNode->SetData(resultReg); + m_spRegNode->SetName(nodeName); + m_spRegNode->AddProperty(mitk::nodeProp_RegAlgUsed,mitk::StringProperty::New(algorithmUID)); + m_spRegNode->AddProperty(mitk::nodeProp_RegAlgMovingData,mitk::StringProperty::New(movingNodeUID)); + m_spRegNode->AddProperty(mitk::nodeProp_RegAlgTargetData,mitk::StringProperty::New(targetNodeUID)); + m_spRegNode->AddProperty(mitk::nodeProp_RegUID,mitk::StringProperty::New(resultReg->GetRegistration()->getRegistrationUID())); + + return m_spRegNode; +}; + + +mitk::DataNode::Pointer + mitk::generateMappedResultNode(const std::string& nodeName, mitk::BaseData::Pointer mappedData, const std::string& regUID, const std::string& inputNodeUID, const bool refinedGeometry, const std::string& interpolator) +{ + if (mappedData.IsNull()) + { + mitkThrow() << "Cannot generate mapping result node. Passed mapped data points to NULL."; + } + + mitk::DataNode::Pointer mappedDataNode = mitk::DataNode::New(); + + mappedDataNode->SetData(mappedData); + mappedDataNode->SetName(nodeName); + if (!regUID.empty()) + { + mappedDataNode->AddProperty(mitk::nodeProp_RegUID, mitk::StringProperty::New(regUID)); + } + mappedDataNode->AddProperty(mitk::nodeProp_MappingInputData,mitk::StringProperty::New(inputNodeUID)); + if (refinedGeometry) + { + mappedDataNode->AddProperty(mitk::nodeProp_MappingInterpolator,mitk::StringProperty::New("None")); + mappedDataNode->AddProperty(mitk::nodeProp_MappingRefinedGeometry,mitk::BoolProperty::New(true)); + } + else + { + mitk::Image* image = dynamic_cast(mappedData.GetPointer()); + + if(image) + { + mappedDataNode->AddProperty(mitk::nodeProp_MappingInterpolator,mitk::StringProperty::New(interpolator)); + } + else + { + mappedDataNode->AddProperty(mitk::nodeProp_MappingInterpolator,mitk::StringProperty::New("None")); + mappedDataNode->SetColor(0.0,0.0,1.0); + } + } + + return mappedDataNode; +}; diff --git a/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.h b/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.h new file mode 100644 index 0000000000..8af0eb0655 --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkResultNodeGenerationHelper.h @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef MITK_RESULT_NODE_GENERATION_HELPER_H +#define MITK_RESULT_NODE_GENERATION_HELPER_H + +#include "mitkDataNode.h" +#include "mitkMAPRegistrationWrapper.h" + +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + /**Method generates a proper result node for the given registration wrapper. + @param nodeName Name of the result node + @param resultReg Pointer to the registration wrapper that should be data of the node. + @param algorithmUID UID string of the algorithm used to generate the result. + @param movingNodeUID UID string of the node used as moving input for the registration algorithm. + @param targetNodeUID UID string of the node used as moving input for the registration algorithm. + @pre registration must point to a valid instance + @result Pointer to a data node with all properties properly set.*/ + MITKMATCHPOINTREGISTRATION_EXPORT mitk::DataNode::Pointer generateRegistrationResultNode(const std::string& nodeName, mitk::MAPRegistrationWrapper::Pointer resultReg, const std::string& algorithmUID, const std::string& movingNodeUID, const std::string& targetNodeUID); + + /**Method generates a proper result node for the given registration wrapper. + @param nodeName Name of the result node + @param mappedData Pointer to the mapped data that should be data of the node. + @param regUID UID string of the registration used to map the data. + @param inputNodeUID UID string of the node used as input for the mapping. + @param refinedGeometry Indicates if the data was really mapped or the geometry was refined. + @param interpolator Name of the used interpolation strategy. + @pre mappedData must point to a valid instance + @result Pointer to a data node with all properties properly set.*/ + MITKMATCHPOINTREGISTRATION_EXPORT mitk::DataNode::Pointer generateMappedResultNode(const std::string& nodeName, mitk::BaseData::Pointer mappedData, const std::string& regUID, const std::string& inputNodeUID, const bool refinedGeometry, const std::string& interpolator = "Unkown"); + +} + +#endif \ No newline at end of file diff --git a/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp new file mode 100644 index 0000000000..6ecc8bd40b --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp @@ -0,0 +1,238 @@ +/*=================================================================== + +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 "itkCommand.h" + +#include "mitkTimeFramesRegistrationHelper.h" +#include +#include + +#include +#include + +mitk::Image::Pointer +mitk::TimeFramesRegistrationHelper::GetFrameImage(const mitk::Image* image, + mitk::TimePointType timePoint) const +{ + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(image); + imageTimeSelector->SetTimeNr(timePoint); + imageTimeSelector->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer frameImage = imageTimeSelector->GetOutput(); + return frameImage; +}; + +void +mitk::TimeFramesRegistrationHelper::Generate() +{ + CheckValidInputs(); + + //prepare processing + mitk::Image::Pointer targetFrame = GetFrameImage(this->m_4DImage, 0); + + this->m_Registered4DImage = this->m_4DImage->Clone(); + + Image::ConstPointer mask; + + if (m_TargetMask.IsNotNull()) + { + if (m_TargetMask->GetTimeSteps() > 1) + { + mask = GetFrameImage(m_TargetMask, 0); + } + else + { + mask = m_TargetMask; + } + } + + double progressDelta = 1.0 / ((this->m_4DImage->GetTimeSteps() - 1) * 3.0); + m_Progress = 0.0; + + //process the frames + for (unsigned int i = 1; i < this->m_4DImage->GetTimeSteps(); ++i) + { + Image::Pointer movingFrame = GetFrameImage(this->m_4DImage, i); + Image::Pointer mappedFrame; + + IgnoreListType::iterator finding = std::find(m_IgnoreList.begin(), m_IgnoreList.end(), i); + + + if (finding == m_IgnoreList.end()) + { + //frame should be processed + RegistrationPointer reg = DoFrameRegistration(movingFrame, targetFrame, mask); + + m_Progress += progressDelta; + this->InvokeEvent(::mitk::FrameRegistrationEvent(0, + "Registred frame #" +::map::core::convert::toStr(i))); + + mappedFrame = DoFrameMapping(movingFrame, reg, targetFrame); + + m_Progress += progressDelta; + this->InvokeEvent(::mitk::FrameMappingEvent(0, + "Mapped frame #" + ::map::core::convert::toStr(i))); + + mitk::ImageReadAccessor accessor(mappedFrame, mappedFrame->GetVolumeData(0, 0, nullptr, + mitk::Image::ReferenceMemory)); + + + this->m_Registered4DImage->SetVolume(accessor.GetData(), i); + this->m_Registered4DImage->GetTimeGeometry()->SetTimeStepGeometry(mappedFrame->GetGeometry(), i); + + m_Progress += progressDelta; + } + else + { + m_Progress += 3 * progressDelta; + } + + this->InvokeEvent(::itk::ProgressEvent()); + + } + +}; + +mitk::Image::Pointer +mitk::TimeFramesRegistrationHelper::GetRegisteredImage() +{ + if (this->HasOutdatedResult()) + { + Generate(); + } + + return m_Registered4DImage; +}; + +void +mitk::TimeFramesRegistrationHelper:: +SetIgnoreList(const IgnoreListType& il) +{ + m_IgnoreList = il; + this->Modified(); +} + +void +mitk::TimeFramesRegistrationHelper::ClearIgnoreList() +{ + m_IgnoreList.clear(); + this->Modified(); +}; + + +mitk::TimeFramesRegistrationHelper::RegistrationPointer +mitk::TimeFramesRegistrationHelper::DoFrameRegistration(const mitk::Image* movingFrame, + const mitk::Image* targetFrame, const mitk::Image* targetMask) const +{ + mitk::MITKAlgorithmHelper algHelper(m_Algorithm); + algHelper.SetAllowImageCasting(true); + algHelper.SetData(movingFrame, targetFrame); + + if (targetMask) + { + mitk::MaskedAlgorithmHelper maskHelper(m_Algorithm); + maskHelper.SetMasks(NULL, targetMask); + } + + return algHelper.GetRegistration(); +}; + +mitk::Image::Pointer mitk::TimeFramesRegistrationHelper::DoFrameMapping( + const mitk::Image* movingFrame, const RegistrationType* reg, const mitk::Image* targetFrame) const +{ + return mitk::ImageMappingHelper::map(movingFrame, reg, !m_AllowUndefPixels, m_PaddingValue, + targetFrame->GetGeometry(), !m_AllowUnregPixels, m_ErrorValue, m_InterpolatorType); +}; + +bool +mitk::TimeFramesRegistrationHelper::HasOutdatedResult() const +{ + if (m_Registered4DImage.IsNull()) + { + return true; + } + + bool result = false; + + if (m_Registered4DImage->GetMTime() > this->GetMTime()) + { + result = true; + } + + + if (m_Algorithm.IsNotNull()) + { + if (m_Algorithm->GetMTime() > this->GetMTime()) + { + result = true; + } + } + + if (m_4DImage.IsNotNull()) + { + if (m_4DImage->GetMTime() > this->GetMTime()) + { + result = true; + } + } + + if (m_TargetMask.IsNotNull()) + { + if (m_TargetMask->GetMTime() > this->GetMTime()) + { + result = true; + } + } + + return result; +}; + +void +mitk::TimeFramesRegistrationHelper::CheckValidInputs() const +{ + if (m_4DImage.IsNull()) + { + mitkThrow() << "Cannot register image. Input 4D image is not set."; + } + + if (m_Algorithm.IsNull()) + { + mitkThrow() << "Cannot register image. Algorithm is not set."; + } + + if (m_4DImage->GetTimeSteps() <= 1) + { + mitkThrow() << "Cannot register image. Input 4D image must have 2 or more time steps."; + } + + for (IgnoreListType::const_iterator pos = this->m_IgnoreList.begin(); + pos != this->m_IgnoreList.end(); ++pos) + { + if (*pos < 0 || *pos >= m_4DImage->GetTimeSteps()) + { + mitkThrow() << + "Cannot register image. Ignore list containes at least one inexistant frame. Invalid frame index: " + << *pos; + } + } +}; + +double +mitk::TimeFramesRegistrationHelper::GetProgress() const +{ + return m_Progress; +}; diff --git a/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.h b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.h new file mode 100644 index 0000000000..c59ceebfcb --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.h @@ -0,0 +1,159 @@ +/*=================================================================== + + The Medical Imaging Interaction Toolkit (MITK) + + Copyright (c) German Cancer Research Center, + Division of Medical and Biological Informatics. + All rights reserved. + + This software is distributed WITHOUT ANY WARRANTY; without + even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. + + See LICENSE.txt or http://www.mitk.org for details. + + ===================================================================*/ + +#ifndef __MITK_TIME_FRAMES_REGISTRATION_HELPER_H_ +#define __MITK_TIME_FRAMES_REGISTRATION_HELPER_H_ + + +#include +#include +#include + +#include +#include +#include + +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + + mapEventMacro(FrameRegistrationEvent, ::map::events::TaskBatchEvent, MITKMATCHPOINTREGISTRATION_EXPORT); + mapEventMacro(FrameMappingEvent, ::map::events::TaskBatchEvent, MITKMATCHPOINTREGISTRATION_EXPORT); + + /** Helper class that assumes that registeres time frames of an passed image and returns the resulting new image. + * A typical use case for the helper class is motion correction in 3D+t images. Each selected frame will be registered + * to the first frame of the image. The user can define frames that may be not registered. These frames will be copied directly. + * Per default all frames will be registered. + * The user may set a mask for the target frame (1st frame). If this mask image has mulitple time steps, the first time step will be used. + * The helper class invokes three eventtypes: \n + * - mitk::FrameRegistrationEvent: when ever a frame was registered. + * - mitk::FrameMappingEvent: when ever a frame was mapped registered. + * - itk::ProgressEvent: when ever a new frame was added to the result image. + */ + class MITKMATCHPOINTREGISTRATION_EXPORT TimeFramesRegistrationHelper : public itk::Object + { + public: + mitkClassMacroItkParent(TimeFramesRegistrationHelper, itk::Object); + + itkNewMacro(Self); + + typedef ::map::algorithm::RegistrationAlgorithmBase RegistrationAlgorithmBaseType; + typedef RegistrationAlgorithmBaseType::Pointer RegistrationAlgorithmPointer; + typedef ::map::core::RegistrationBase RegistrationType; + typedef RegistrationType::Pointer RegistrationPointer; + + typedef std::vector IgnoreListType; + + itkSetConstObjectMacro(4DImage, Image); + itkGetConstObjectMacro(4DImage, Image); + + itkSetConstObjectMacro(TargetMask, Image); + itkGetConstObjectMacro(TargetMask, Image); + + itkSetObjectMacro(Algorithm, RegistrationAlgorithmBaseType); + itkGetObjectMacro(Algorithm, RegistrationAlgorithmBaseType); + + itkSetMacro(AllowUndefPixels, bool); + itkGetConstMacro(AllowUndefPixels, bool); + + itkSetMacro(PaddingValue, double); + itkGetConstMacro(PaddingValue, double); + + itkSetMacro(AllowUnregPixels, bool); + itkGetConstMacro(AllowUnregPixels, bool); + + itkSetMacro(ErrorValue, double); + itkGetConstMacro(ErrorValue, double); + + itkSetMacro(InterpolatorType, mitk::ImageMappingInterpolator::Type); + itkGetConstMacro(InterpolatorType, mitk::ImageMappingInterpolator::Type); + + /** cleares the ignore list. Therefore all frames will be processed.*/ + void ClearIgnoreList(); + void SetIgnoreList(const IgnoreListType& il); + itkGetConstMacro(IgnoreList, IgnoreListType); + + virtual double GetProgress() const; + + /** Commences the generation of the registered 4D image. Stores the result internally. + * After this method call is finished the result can be retrieved via + * GetRegisteredImage. + * @pre 4D image must be set + * @pre 4D image must has more then one frame + * @pre Reg algorithm must be set + * @pre Ignore list values must be within the time geometry of the image + * @post Result image was generated.*/ + void Generate(); + + /** Returns the generated images. Triggers Generate() if result is outdated. + * @pre 4D image must be set + * @pre 4D image must has more then one frame + * @pre Reg algorithm must be set + * @pre Ignore list values must be within the time geometry of the image + */ + Image::Pointer GetRegisteredImage(); + + protected: + TimeFramesRegistrationHelper() : m_Progress(0), m_AllowUndefPixels(true), m_PaddingValue(0), + m_AllowUnregPixels(true), m_ErrorValue(0), m_InterpolatorType(mitk::ImageMappingInterpolator::Linear) + { + m_4DImage = NULL; + m_TargetMask = NULL; + m_Registered4DImage = NULL; + }; + + ~TimeFramesRegistrationHelper() {}; + + RegistrationPointer DoFrameRegistration(const mitk::Image* movingFrame, + const mitk::Image* targetFrame, const mitk::Image* targetMask) const; + + mitk::Image::Pointer DoFrameMapping(const mitk::Image* movingFrame, const RegistrationType* reg, + const mitk::Image* targetFrame) const; + + bool HasOutdatedResult() const; + /** Check if the fit can be generated and all needed inputs are valid. + * Throw an exception for a non valid or missing input.*/ + void CheckValidInputs() const; + + mitk::Image::Pointer GetFrameImage(const mitk::Image* image, mitk::TimePointType timePoint) const; + + RegistrationAlgorithmPointer m_Algorithm; + + private: + Image::ConstPointer m_4DImage; + Image::ConstPointer m_TargetMask; + Image::Pointer m_Registered4DImage; + + IgnoreListType m_IgnoreList; + + /**Indicates if the mapper should allow undefined pixels (true) or mapping should fail (false)*/ + bool m_AllowUndefPixels; + /** Value of undefined pixels. Only relevant if m_allowUndefPixels is true. */ + double m_PaddingValue; + /**Indicates if the mapper should allow pixels that are not covered by the registration (true) or mapping should fail (false)*/ + bool m_AllowUnregPixels; + /** Value of unreged pixels. Only relevant if m_allowUnregPixels is true. */ + double m_ErrorValue; + /** Type of interpolator. Only relevant for images and if m_doGeometryRefinement is false. */ + mitk::ImageMappingInterpolator::Type m_InterpolatorType; + + double m_Progress; + }; + +} + +#endif // __MITK_PARAMETER_FIT_IMAGE_GENERATOR_H_ diff --git a/Modules/MatchPointRegistration/Helper/mitkUIDHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkUIDHelper.cpp new file mode 100644 index 0000000000..b9bb54215d --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkUIDHelper.cpp @@ -0,0 +1,57 @@ +/*=================================================================== + +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 "mitkUIDHelper.h" + + +// Mitk +#include +#include + +mitk::NodeUIDType mitk::EnsureUID(mitk::DataNode* node) +{ + if (!node) + { + mitkThrow() << "Cannot ensure node UID. Passed node pointer is NULL."; + } + + std::string propUID = ""; + if (!node->GetStringProperty(mitk::nodeProp_UID,propUID)) + { + mitk::UIDGenerator generator; + propUID = generator.GetUID(); + + node->SetStringProperty(mitk::nodeProp_UID,propUID.c_str()); + } + + return propUID; +}; + +bool mitk::CheckUID(const mitk::DataNode* node, const NodeUIDType& uid) +{ + bool result = false; + + if (node) + { + std::string propUID = ""; + if (node->GetStringProperty(mitk::nodeProp_UID,propUID)) + { + result = propUID == uid; + } + } + + return result; +}; diff --git a/Modules/MatchPointRegistration/Helper/mitkUIDHelper.h b/Modules/MatchPointRegistration/Helper/mitkUIDHelper.h new file mode 100644 index 0000000000..9a27a57f8e --- /dev/null +++ b/Modules/MatchPointRegistration/Helper/mitkUIDHelper.h @@ -0,0 +1,43 @@ +/*=================================================================== + +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 mitkUIDHelper_h +#define mitkUIDHelper_h + +//MITK +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" +#include "mitkMatchPointPropertyTags.h" + +namespace mitk +{ + + typedef std::string NodeUIDType; + + /** Gets the content of the property "matchpoint.uid". If it does not exist, the property will be added with a new UID. + @pre Passed node is a valid pointer.*/ + NodeUIDType MITKMATCHPOINTREGISTRATION_EXPORT EnsureUID(mitk::DataNode* node); + + /** Helper that checks if the content of property "matchpoint.uid" equals the passed uid. If the property does not exist or node is invalid, return will be false.*/ + bool MITKMATCHPOINTREGISTRATION_EXPORT CheckUID(const mitk::DataNode* node, const NodeUIDType& uid); + +} + +#endif + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.cpp new file mode 100644 index 0000000000..465a27d395 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.cpp @@ -0,0 +1,68 @@ +/*=================================================================== + +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 "mitkRegEvalStyleProperty.h" + + +mitk::RegEvalStyleProperty::RegEvalStyleProperty( ) +{ + AddTypes(); + SetValue( 0 ); +} + + +mitk::RegEvalStyleProperty::RegEvalStyleProperty( const IdType& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ) ; + } + else + { + SetValue( 0 ); + } +} + +mitk::RegEvalStyleProperty::RegEvalStyleProperty( const std::string& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ); + } + else + { + SetValue( 0 ); + } +} + +void mitk::RegEvalStyleProperty::AddTypes() +{ + AddEnum( "Blend", static_cast( 0 ) ); + AddEnum( "Color Blend", static_cast( 1 ) ); + AddEnum( "Checkerboard", static_cast( 2 ) ); + AddEnum( "Wipe", static_cast( 3 ) ); + AddEnum( "Difference", static_cast( 4 ) ); + AddEnum( "Contour", static_cast( 5 ) ); +} + + +bool mitk::RegEvalStyleProperty::AddEnum( const std::string& name, const IdType& id ) +{ + return Superclass::AddEnum( name, id ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.h b/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.h new file mode 100644 index 0000000000..e8227b5aa5 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvalStyleProperty.h @@ -0,0 +1,100 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_EVAL_STYLE_PROPERTY__H_ +#define _MITK_REG_EVAL_STYLE_PROPERTY__H_ + +// MITK +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + +/** + * Encapsulates the enumeration for visualization styles. Valid values are: + * 0/Blend 1/Color Blend 2/Checkerboard, 3/Wipe, 4/Difference, 5/Contour + * Default is "Blend" + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegEvalStyleProperty : public EnumerationProperty +{ +public: + + mitkClassMacro( RegEvalStyleProperty, EnumerationProperty ); + + itkNewMacro(RegEvalStyleProperty); + + mitkNewMacro1Param(RegEvalStyleProperty, const IdType&); + + mitkNewMacro1Param(RegEvalStyleProperty, const std::string&); + + + using BaseProperty::operator=; + +protected: + + /** + * Constructor. Sets the representation to a default value of 0 + */ + RegEvalStyleProperty( ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegEvalStyleProperty( const IdType& value ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegEvalStyleProperty( const std::string& value ); + + /** + * this function is overridden as protected, so that the user may not add + * additional invalid interpolation types. + */ + virtual bool AddEnum( const std::string& name, const IdType& id ); + + /** + * Adds the enumeration types + */ + virtual void AddTypes(); + +private: + + // purposely not implemented + RegEvalStyleProperty(const RegEvalStyleProperty&); + RegEvalStyleProperty& operator=(const RegEvalStyleProperty&); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // end of namespace mitk + +#endif + + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.cpp new file mode 100644 index 0000000000..84233be399 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.cpp @@ -0,0 +1,65 @@ +/*=================================================================== + +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 "mitkRegEvalWipeStyleProperty.h" + + +mitk::RegEvalWipeStyleProperty::RegEvalWipeStyleProperty( ) +{ + AddTypes(); + SetValue( 0 ); +} + + +mitk::RegEvalWipeStyleProperty::RegEvalWipeStyleProperty( const IdType& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ) ; + } + else + { + SetValue( 0 ); + } +} + +mitk::RegEvalWipeStyleProperty::RegEvalWipeStyleProperty( const std::string& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ); + } + else + { + SetValue( 0 ); + } +} + +void mitk::RegEvalWipeStyleProperty::AddTypes() +{ + AddEnum( "Cross", static_cast( 0 ) ); + AddEnum( "Horizontal wipe", static_cast( 1 ) ); + AddEnum( "Vertical wipe", static_cast( 2 ) ); +} + + +bool mitk::RegEvalWipeStyleProperty::AddEnum( const std::string& name, const IdType& id ) +{ + return Superclass::AddEnum( name, id ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.h b/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.h new file mode 100644 index 0000000000..25e114cadc --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvalWipeStyleProperty.h @@ -0,0 +1,100 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_EVAL_WIPE_STYLE_PROPERTY__H_ +#define _MITK_REG_EVAL_WIPE_STYLE_PROPERTY__H_ + +// MITK +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + +/** + * Encapsulates the enumeration for visualization styles. Valid values are: + * 0/Cross 1/horizontal wipe 2/vertical wipe + * Default is "Cross" + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegEvalWipeStyleProperty : public EnumerationProperty +{ +public: + + mitkClassMacro( RegEvalWipeStyleProperty, EnumerationProperty ); + + itkNewMacro(RegEvalWipeStyleProperty); + + mitkNewMacro1Param(RegEvalWipeStyleProperty, const IdType&); + + mitkNewMacro1Param(RegEvalWipeStyleProperty, const std::string&); + + + using BaseProperty::operator=; + +protected: + + /** + * Constructor. Sets the representation to a default value of 0 + */ + RegEvalWipeStyleProperty( ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegEvalWipeStyleProperty( const IdType& value ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegEvalWipeStyleProperty( const std::string& value ); + + /** + * this function is overridden as protected, so that the user may not add + * additional invalid interpolation types. + */ + virtual bool AddEnum( const std::string& name, const IdType& id ); + + /** + * Adds the enumeration types + */ + virtual void AddTypes(); + +private: + + // purposely not implemented + RegEvalWipeStyleProperty(const RegEvalWipeStyleProperty&); + RegEvalWipeStyleProperty& operator=(const RegEvalWipeStyleProperty&); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // end of namespace mitk + +#endif + + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.cpp new file mode 100644 index 0000000000..f4d718687d --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.cpp @@ -0,0 +1,825 @@ +/*=================================================================== + +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. + +===================================================================*/ + +//MITK +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mitkImageStatisticsHolder.h" +#include "mitkPlaneClipping.h" + +#include "mitkRegVisPropertyTags.h" +#include "mitkRegVisHelper.h" +#include "mitkRegEvalStyleProperty.h" +#include "mitkRegEvalWipeStyleProperty.h" + +//MITK Rendering +#include "mitkRegEvaluationMapper2D.h" +#include "vtkMitkThickSlicesFilter.h" +#include "vtkMitkLevelWindowFilter.h" +#include "vtkNeverTranslucentTexture.h" + +//VTK +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//ITK +#include +#include + +//MatchPoint +#include +#include + +mitk::RegEvaluationMapper2D::RegEvaluationMapper2D() +{ +} + +mitk::RegEvaluationMapper2D::~RegEvaluationMapper2D() +{ +} + +//set the two points defining the textured plane according to the dimension and spacing +void mitk::RegEvaluationMapper2D::GeneratePlane(mitk::BaseRenderer* renderer, double planeBounds[6]) +{ + LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + + float depth = this->CalculateLayerDepth(renderer); + //Set the origin to (xMin; yMin; depth) of the plane. This is necessary for obtaining the correct + //plane size in crosshair rotation and swivel mode. + localStorage->m_Plane->SetOrigin(planeBounds[0], planeBounds[2], depth); + //These two points define the axes of the plane in combination with the origin. + //Point 1 is the x-axis and point 2 the y-axis. + //Each plane is transformed according to the view (axial, coronal and saggital) afterwards. + localStorage->m_Plane->SetPoint1(planeBounds[1] , planeBounds[2], depth); //P1: (xMax, yMin, depth) + localStorage->m_Plane->SetPoint2(planeBounds[0], planeBounds[3], depth); //P2: (xMin, yMax, depth) +} + +float mitk::RegEvaluationMapper2D::CalculateLayerDepth(mitk::BaseRenderer* renderer) +{ + //get the clipping range to check how deep into z direction we can render images + double maxRange = renderer->GetVtkRenderer()->GetActiveCamera()->GetClippingRange()[1]; + + //Due to a VTK bug, we cannot use the whole clipping range. /100 is empirically determined + float depth = -maxRange*0.01; // divide by 100 + int layer = 0; + GetDataNode()->GetIntProperty( "layer", layer, renderer); + //add the layer property for each image to render images with a higher layer on top of the others + depth += layer*10; //*10: keep some room for each image (e.g. for QBalls in between) + if(depth > 0.0f) { + depth = 0.0f; + MITK_WARN << "Layer value exceeds clipping range. Set to minimum instead."; + } + return depth; +} + +const mitk::Image* mitk::RegEvaluationMapper2D::GetTargetImage( void ) +{ + const mitk::RegEvaluationObject* evalObj = dynamic_cast< const mitk::RegEvaluationObject* >( GetDataNode()->GetData() ); + if (evalObj) + { + return evalObj->GetTargetImage(); + } + + return NULL; +} + +const mitk::Image* mitk::RegEvaluationMapper2D::GetMovingImage( void ) +{ + const mitk::RegEvaluationObject* evalObj = dynamic_cast< const mitk::RegEvaluationObject* >( GetDataNode()->GetData() ); + if (evalObj) + { + return evalObj->GetMovingImage(); + } + + return NULL; +} + +const mitk::MAPRegistrationWrapper* mitk::RegEvaluationMapper2D::GetRegistration( void ) +{ + const mitk::RegEvaluationObject* evalObj = dynamic_cast< const mitk::RegEvaluationObject* >( GetDataNode()->GetData() ); + if (evalObj) + { + return evalObj->GetRegistration(); + } + + return NULL; +} + +vtkProp* mitk::RegEvaluationMapper2D::GetVtkProp(mitk::BaseRenderer* renderer) +{ + //return the actor corresponding to the renderer + return m_LSH.GetLocalStorage(renderer)->m_Actors; +} + +void mitk::RegEvaluationMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) +{ + bool updated = false; + LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + + mitk::Image::Pointer targetInput = const_cast< mitk::Image * >( this->GetTargetImage() ); + mitk::DataNode* datanode = this->GetDataNode(); + + if ( targetInput.IsNull() || targetInput->IsInitialized() == false ) + { + return; + } + + mitk::Image::ConstPointer movingInput = this->GetMovingImage(); + + if ( movingInput.IsNull() || movingInput->IsInitialized() == false ) + { + return; + } + + mitk::MAPRegistrationWrapper::ConstPointer reg = this->GetRegistration(); + + //check if there is a valid worldGeometry + const Geometry2D *worldGeometry = renderer->GetCurrentWorldGeometry2D(); + if( ( worldGeometry == NULL ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() )) + { + return; + } + + if(targetInput->GetMTime()>localStorage->m_LastUpdateTime + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime())) + { //target input has been modified -> reslice target input + targetInput->Update(); + + // early out if there is no intersection of the current rendering geometry + // and the geometry of the image that is to be rendered. + if ( !RenderingGeometryIntersectsImage( worldGeometry, targetInput->GetSlicedGeometry() ) ) + { + // set image to NULL, to clear the texture in 3D, because + // the latest image is used there if the plane is out of the geometry + // see bug-13275 + localStorage->m_EvaluationImage = NULL; + localStorage->m_Mapper->SetInputData( localStorage->m_EmptyPolyData ); + return; + } + + //set main input for ExtractSliceFilter + localStorage->m_Reslicer->SetInput(targetInput); + localStorage->m_Reslicer->SetWorldGeometry(worldGeometry); + localStorage->m_Reslicer->SetTimeStep( this->GetTimestep() ); + + + //set the transformation of the image to adapt reslice axis + localStorage->m_Reslicer->SetResliceTransformByGeometry( targetInput->GetTimeGeometry()->GetGeometryForTimeStep( this->GetTimestep() ) ); + + + //is the geometry of the slice based on the input image or the worldgeometry? + bool inPlaneResampleExtentByGeometry = false; + datanode->GetBoolProperty("in plane resample extent by geometry", inPlaneResampleExtentByGeometry, renderer); + localStorage->m_Reslicer->SetInPlaneResampleExtentByGeometry(inPlaneResampleExtentByGeometry); + + + // Initialize the interpolation mode for resampling; switch to nearest + // neighbor if the input image is too small. + if ( (targetInput->GetDimension() >= 3) && (targetInput->GetDimension(2) > 1) ) + { + VtkResliceInterpolationProperty *resliceInterpolationProperty; + datanode->GetProperty( + resliceInterpolationProperty, "reslice interpolation" ); + + int interpolationMode = VTK_RESLICE_NEAREST; + if ( resliceInterpolationProperty != NULL ) + { + interpolationMode = resliceInterpolationProperty->GetInterpolation(); + } + + switch ( interpolationMode ) + { + case VTK_RESLICE_NEAREST: + localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST); + break; + case VTK_RESLICE_LINEAR: + localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_LINEAR); + break; + case VTK_RESLICE_CUBIC: + localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_CUBIC); + break; + } + } + else + { + localStorage->m_Reslicer->SetInterpolationMode(ExtractSliceFilter::RESLICE_NEAREST); + } + + //this is needed when thick mode was enable bevore. These variable have to be reset to default values + localStorage->m_Reslicer->SetOutputDimensionality( 2 ); + localStorage->m_Reslicer->SetOutputSpacingZDirection(1.0); + localStorage->m_Reslicer->SetOutputExtentZDirection( 0, 0 ); + + localStorage->m_Reslicer->Modified(); + //start the pipeline with updating the largest possible, needed if the geometry of the input has changed + localStorage->m_Reslicer->UpdateLargestPossibleRegion(); + localStorage->m_slicedTargetImage = localStorage->m_Reslicer->GetOutput(); + updated = true; + } + + if(updated || + movingInput->GetMTime() > localStorage->m_LastUpdateTime || + reg->GetMTime() > localStorage->m_LastUpdateTime) + { + //Map moving image + localStorage->m_slicedMappedImage = mitk::ImageMappingHelper::map(movingInput,reg,false,0,localStorage->m_slicedTargetImage->GetGeometry(),false,0); + updated = true; + } + + //Generate evaulation image + bool isStyleOutdated = mitk::PropertyIsOutdated(datanode,mitk::nodeProp_RegEvalStyle,localStorage->m_LastUpdateTime); + bool isBlendOutdated = mitk::PropertyIsOutdated(datanode,mitk::nodeProp_RegEvalBlendFactor,localStorage->m_LastUpdateTime); + bool isCheckerOutdated = mitk::PropertyIsOutdated(datanode,mitk::nodeProp_RegEvalCheckerCount,localStorage->m_LastUpdateTime); + bool isWipeStyleOutdated = mitk::PropertyIsOutdated(datanode,mitk::nodeProp_RegEvalWipeStyle,localStorage->m_LastUpdateTime); + bool isContourOutdated = mitk::PropertyIsOutdated(datanode,mitk::nodeProp_RegEvalTargetContour,localStorage->m_LastUpdateTime); + + if (updated || + isStyleOutdated || + isBlendOutdated || + isCheckerOutdated || + isWipeStyleOutdated || + isContourOutdated) + { + mitk::RegEvalStyleProperty::Pointer evalStyleProp = mitk::RegEvalStyleProperty::New(); + datanode->GetProperty(evalStyleProp, mitk::nodeProp_RegEvalStyle); + + switch (evalStyleProp->GetValueAsId()) + { + case 0 : + { + PrepareBlend(datanode, localStorage); + break; + } + case 1 : + { + PrepareColorBlend(localStorage); + break; + } + case 2 : + { + PrepareCheckerBoard(datanode, localStorage); + break; + } + case 3 : + { + PrepareWipe(datanode, localStorage); + break; + } + case 4 : + { + PrepareDifference(localStorage); + break; + } + case 5 : + { + PrepareContour(datanode, localStorage); + break; + } + } + updated = true; + } + + if(updated + || (localStorage->m_LastUpdateTime < datanode->GetPropertyList()->GetMTime()) //was a property modified? + || (localStorage->m_LastUpdateTime < datanode->GetPropertyList(renderer)->GetMTime()) ) + { + // Bounds information for reslicing (only required if reference geometry + // is present) + //this used for generating a vtkPLaneSource with the right size + double sliceBounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + localStorage->m_Reslicer->GetClippedPlaneBounds(sliceBounds); + + //get the spacing of the slice + localStorage->m_mmPerPixel = localStorage->m_Reslicer->GetOutputSpacing(); + + // calculate minimum bounding rect of IMAGE in texture + { + double textureClippingBounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + + // Calculate the actual bounds of the transformed plane clipped by the + // dataset bounding box; this is required for drawing the texture at the + // correct position during 3D mapping. + + const PlaneGeometry *planeGeometry = dynamic_cast< const PlaneGeometry * >( worldGeometry ); + mitk::PlaneClipping::CalculateClippedPlaneBounds( targetInput->GetGeometry(), planeGeometry, textureClippingBounds ); + + textureClippingBounds[0] = static_cast< int >( textureClippingBounds[0] / localStorage->m_mmPerPixel[0] + 0.5 ); + textureClippingBounds[1] = static_cast< int >( textureClippingBounds[1] / localStorage->m_mmPerPixel[0] + 0.5 ); + textureClippingBounds[2] = static_cast< int >( textureClippingBounds[2] / localStorage->m_mmPerPixel[1] + 0.5 ); + textureClippingBounds[3] = static_cast< int >( textureClippingBounds[3] / localStorage->m_mmPerPixel[1] + 0.5 ); + + //clipping bounds for cutting the image + localStorage->m_LevelWindowFilter->SetClippingBounds(textureClippingBounds); + } + + this->ApplyOpacity( renderer ); + + this->ApplyLookuptable( renderer ); + this->ApplyLevelWindow( renderer ); + this->ApplyColor( renderer ); + + // do not use a VTK lookup table (we do that ourselves in m_LevelWindowFilter) + localStorage->m_Texture->MapColorScalarsThroughLookupTableOff(); + + //connect the input with the levelwindow filter + localStorage->m_LevelWindowFilter->SetInputData(localStorage->m_EvaluationImage); + + // check for texture interpolation property + bool textureInterpolation = false; + GetDataNode()->GetBoolProperty( "texture interpolation", textureInterpolation, renderer ); + + //set the interpolation modus according to the property + localStorage->m_Texture->SetInterpolate(textureInterpolation); + + // connect the texture with the output of the levelwindow filter + localStorage->m_Texture->SetInputConnection(localStorage->m_LevelWindowFilter->GetOutputPort()); + + this->TransformActor( renderer ); + + vtkActor* contourShadowActor = dynamic_cast (localStorage->m_Actors->GetParts()->GetItemAsObject(0)); + + //Connect the mapper with the input texture. This is the standard case. + //setup the textured plane + this->GeneratePlane( renderer, sliceBounds ); + //set the plane as input for the mapper + localStorage->m_Mapper->SetInputConnection(localStorage->m_Plane->GetOutputPort()); + //set the texture for the actor + + localStorage->m_Actor->SetTexture(localStorage->m_Texture); + contourShadowActor->SetVisibility( false ); + + // We have been modified => save this for next Update() + localStorage->m_LastUpdateTime.Modified(); + } +} + + +void mitk::RegEvaluationMapper2D::PrepareContour( mitk::DataNode* datanode, LocalStorage * localStorage ) +{ + bool targetContour = true; + datanode->GetBoolProperty(mitk::nodeProp_RegEvalTargetContour,targetContour); + + vtkSmartPointer magFilter = + vtkSmartPointer::New(); + if(targetContour) + { + magFilter->AddInputData(localStorage->m_slicedTargetImage->GetVtkImageData()); + } + else + { + magFilter->AddInputData(localStorage->m_slicedMappedImage->GetVtkImageData()); + } + + vtkSmartPointer appendFilter = + vtkSmartPointer::New(); + + appendFilter->AddInputConnection(magFilter->GetOutputPort()); + appendFilter->AddInputConnection(magFilter->GetOutputPort()); + if(targetContour) + { + appendFilter->AddInputData(localStorage->m_slicedMappedImage->GetVtkImageData()); + } + else + { + appendFilter->AddInputData(localStorage->m_slicedTargetImage->GetVtkImageData()); + } + appendFilter->Update(); + + localStorage->m_EvaluationImage = appendFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::PrepareDifference( LocalStorage * localStorage ) +{ + vtkSmartPointer diffFilter = + vtkSmartPointer::New(); + vtkSmartPointer absFilter = + vtkSmartPointer::New(); + diffFilter->SetInput1Data(localStorage->m_slicedTargetImage->GetVtkImageData()); + diffFilter->SetInput2Data(localStorage->m_slicedMappedImage->GetVtkImageData()); + diffFilter->SetOperationToSubtract(); + absFilter->SetInputConnection(diffFilter->GetOutputPort()); + absFilter->SetOperationToAbsoluteValue(); + diffFilter->Update(); + localStorage->m_EvaluationImage = diffFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::PrepareWipe( mitk::DataNode* datanode, LocalStorage * localStorage ) +{ + mitk::RegEvalWipeStyleProperty::Pointer evalWipeStyleProp = mitk::RegEvalWipeStyleProperty::New(); + datanode->GetProperty(evalWipeStyleProp, mitk::nodeProp_RegEvalWipeStyle); + + vtkSmartPointer wipedFilter = + vtkSmartPointer::New(); + wipedFilter->SetInput1Data(localStorage->m_slicedTargetImage->GetVtkImageData()); + wipedFilter->SetInput2Data(localStorage->m_slicedMappedImage->GetVtkImageData()); + wipedFilter->SetPosition(30,30); + + if (evalWipeStyleProp->GetValueAsId() == 0) + { + wipedFilter->SetWipeToQuad(); + } + else if (evalWipeStyleProp->GetValueAsId() == 1) + { + wipedFilter->SetWipeToHorizontal(); + } + else if (evalWipeStyleProp->GetValueAsId() == 2) + { + wipedFilter->SetWipeToVertical(); + } + + wipedFilter->Update(); + + localStorage->m_EvaluationImage = wipedFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::PrepareCheckerBoard( mitk::DataNode* datanode, LocalStorage * localStorage ) +{ + int checkerCount = 5; + datanode->GetIntProperty(mitk::nodeProp_RegEvalCheckerCount,checkerCount); + + vtkSmartPointer checkerboardFilter = + vtkSmartPointer::New(); + checkerboardFilter->SetInput1Data(localStorage->m_slicedTargetImage->GetVtkImageData()); + checkerboardFilter->SetInput2Data(localStorage->m_slicedMappedImage->GetVtkImageData()); + checkerboardFilter->SetNumberOfDivisions(checkerCount,checkerCount,1); + checkerboardFilter->Update(); + + localStorage->m_EvaluationImage = checkerboardFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::PrepareColorBlend( LocalStorage * localStorage ) +{ + vtkSmartPointer appendFilter = + vtkSmartPointer::New(); + //red channel + appendFilter->AddInputData(localStorage->m_slicedMappedImage->GetVtkImageData()); + //green channel + appendFilter->AddInputData(localStorage->m_slicedMappedImage->GetVtkImageData()); + //blue channel + appendFilter->AddInputData(localStorage->m_slicedTargetImage->GetVtkImageData()); + appendFilter->Update(); + + localStorage->m_EvaluationImage = appendFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::PrepareBlend( mitk::DataNode* datanode, LocalStorage * localStorage ) +{ + int blendfactor = 50; + datanode->GetIntProperty(mitk::nodeProp_RegEvalBlendFactor,blendfactor); + + vtkSmartPointer blendFilter = + vtkSmartPointer::New(); + blendFilter->AddInputData(localStorage->m_slicedTargetImage->GetVtkImageData()); + blendFilter->AddInputData(localStorage->m_slicedMappedImage->GetVtkImageData()); + blendFilter->SetWeight(0,(100-blendfactor)/100.); + blendFilter->SetWeight(1,blendfactor/100.); + blendFilter->Update(); + + localStorage->m_EvaluationImage = blendFilter->GetOutput(); +} + +void mitk::RegEvaluationMapper2D::ApplyLevelWindow(mitk::BaseRenderer *renderer) +{ + LocalStorage *localStorage = this->GetLocalStorage( renderer ); + + LevelWindow levelWindow; + this->GetDataNode()->GetLevelWindow( levelWindow, renderer, "levelwindow" ); + localStorage->m_LevelWindowFilter->GetLookupTable()->SetRange( levelWindow.GetLowerWindowBound(), levelWindow.GetUpperWindowBound() ); + + mitk::LevelWindow opacLevelWindow; + if( this->GetDataNode()->GetLevelWindow( opacLevelWindow, renderer, "opaclevelwindow" ) ) + { + //pass the opaque level window to the filter + localStorage->m_LevelWindowFilter->SetMinOpacity(opacLevelWindow.GetLowerWindowBound()); + localStorage->m_LevelWindowFilter->SetMaxOpacity(opacLevelWindow.GetUpperWindowBound()); + } + else + { + //no opaque level window + localStorage->m_LevelWindowFilter->SetMinOpacity(0.0); + localStorage->m_LevelWindowFilter->SetMaxOpacity(255.0); + } +} + +void mitk::RegEvaluationMapper2D::ApplyColor( mitk::BaseRenderer* renderer ) +{ + LocalStorage *localStorage = this->GetLocalStorage( renderer ); + + float rgb[3]= { 1.0f, 1.0f, 1.0f }; + + // check for color prop and use it for rendering if it exists + // binary image hovering & binary image selection + bool hover = false; + bool selected = false; + GetDataNode()->GetBoolProperty("binaryimage.ishovering", hover, renderer); + GetDataNode()->GetBoolProperty("selected", selected, renderer); + if(hover && !selected) + { + mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty + ("binaryimage.hoveringcolor", renderer)); + if(colorprop.IsNotNull()) + { + memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); + } + else + { + GetDataNode()->GetColor( rgb, renderer, "color" ); + } + } + if(selected) + { + mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty + ("binaryimage.selectedcolor", renderer)); + if(colorprop.IsNotNull()) { + memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); + } + else + { + GetDataNode()->GetColor(rgb, renderer, "color"); + } + } + if(!hover && !selected) + { + GetDataNode()->GetColor( rgb, renderer, "color" ); + } + + double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK + dynamic_cast (localStorage->m_Actors->GetParts()->GetItemAsObject(0))->GetProperty()->SetColor(rgbConv); + localStorage->m_Actor->GetProperty()->SetColor(rgbConv); + + if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 ) + { + float rgb[3]= { 1.0f, 1.0f, 1.0f }; + mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetDataNode()->GetProperty + ("outline binary shadow color", renderer)); + if(colorprop.IsNotNull()) + { + memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3*sizeof(float)); + } + double rgbConv[3] = {(double)rgb[0], (double)rgb[1], (double)rgb[2]}; //conversion to double for VTK + dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetColor(rgbConv); + } +} + +void mitk::RegEvaluationMapper2D::ApplyOpacity( mitk::BaseRenderer* renderer ) +{ + LocalStorage* localStorage = this->GetLocalStorage( renderer ); + float opacity = 1.0f; + // check for opacity prop and use it for rendering if it exists + GetDataNode()->GetOpacity( opacity, renderer, "opacity" ); + //set the opacity according to the properties + localStorage->m_Actor->GetProperty()->SetOpacity(opacity); + if ( localStorage->m_Actors->GetParts()->GetNumberOfItems() > 1 ) + { + dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) )->GetProperty()->SetOpacity(opacity); + } +} + +void mitk::RegEvaluationMapper2D::ApplyLookuptable( mitk::BaseRenderer* renderer ) +{ + LocalStorage* localStorage = m_LSH.GetLocalStorage(renderer); + vtkLookupTable* usedLookupTable = localStorage->m_ColorLookupTable; + + // If lookup table or transferfunction use is requested... + mitk::LookupTableProperty::Pointer lookupTableProp = dynamic_cast(this->GetDataNode()->GetProperty("LookupTable")); + + if( lookupTableProp.IsNotNull() ) // is a lookuptable set? + { + usedLookupTable = lookupTableProp->GetLookupTable()->GetVtkLookupTable(); + } + else + { + //"Image Rendering.Mode was set to use a lookup table but there is no property 'LookupTable'. + //A default (rainbow) lookup table will be used. + //Here have to do nothing. Warning for the user has been removed, due to unwanted console output + //in every interation of the rendering. + } + localStorage->m_LevelWindowFilter->SetLookupTable(usedLookupTable); +} + +void mitk::RegEvaluationMapper2D::Update(mitk::BaseRenderer* renderer) +{ + + bool visible = true; + GetDataNode()->GetVisibility(visible, renderer, "visible"); + + if ( !visible ) + { + return; + } + + mitk::Image* data = const_cast( this->GetTargetImage() ); + if ( data == NULL ) + { + return; + } + + // Calculate time step of the input data for the specified renderer (integer value) + this->CalculateTimeStep( renderer ); + + // Check if time step is valid + const TimeGeometry *dataTimeGeometry = data->GetTimeGeometry(); + if ( ( dataTimeGeometry == NULL ) + || ( dataTimeGeometry->CountTimeSteps() == 0 ) + || ( !dataTimeGeometry->IsValidTimeStep( this->GetTimestep() ) ) ) + { + return; + } + + const DataNode *node = this->GetDataNode(); + data->UpdateOutputInformation(); + LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + + //check if something important has changed and we need to rerender + if ( (localStorage->m_LastUpdateTime < node->GetMTime()) //was the node modified? + || (localStorage->m_LastUpdateTime < data->GetPipelineMTime()) //Was the data modified? + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? + || (localStorage->m_LastUpdateTime < renderer->GetCurrentWorldGeometry2D()->GetMTime()) + || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? + || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) ) + { + this->GenerateDataForRenderer( renderer ); + } + + // since we have checked that nothing important has changed, we can set + // m_LastUpdateTime to the current time + localStorage->m_LastUpdateTime.Modified(); +} + +void mitk::RegEvaluationMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) +{ + mitk::RegEvaluationObject* regEval = dynamic_cast(node->GetData()); + + if(!regEval) + { + return; + } + + // Properties common for both images and segmentations + node->AddProperty( "depthOffset", mitk::FloatProperty::New( 0.0 ), renderer, overwrite ); + if(regEval->GetTargetImage() && regEval->GetTargetImage()->IsRotated()) node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_CUBIC) ); + else node->AddProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New() ); + node->AddProperty( "texture interpolation", mitk::BoolProperty::New( false ) ); // set to user configurable default value (see global options) + node->AddProperty( "in plane resample extent by geometry", mitk::BoolProperty::New( false ) ); + node->AddProperty( "bounding box", mitk::BoolProperty::New( false ) ); + + mitk::RenderingModeProperty::Pointer renderingModeProperty = mitk::RenderingModeProperty::New(); + node->AddProperty( "Image Rendering.Mode", renderingModeProperty); + + // Set default grayscale look-up table + mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New(); + mitk::LookupTableProperty::Pointer mitkLutProp = mitk::LookupTableProperty::New(); + mitkLutProp->SetLookupTable(mitkLut); + node->SetProperty("LookupTable", mitkLutProp); + + node->AddProperty( "opacity", mitk::FloatProperty::New(1.0f), renderer, overwrite ); + node->AddProperty( "color", ColorProperty::New(1.0,1.0,1.0), renderer, overwrite ); + node->AddProperty( "binary", mitk::BoolProperty::New( false ), renderer, overwrite ); + node->AddProperty("layer", mitk::IntProperty::New(0), renderer, overwrite); + + node->AddProperty(mitk::nodeProp_RegEvalStyle, mitk::RegEvalStyleProperty::New(0), renderer, overwrite); + node->AddProperty(mitk::nodeProp_RegEvalBlendFactor, mitk::IntProperty::New(50), renderer, overwrite); + node->AddProperty(mitk::nodeProp_RegEvalCheckerCount, mitk::IntProperty::New(3), renderer, overwrite); + node->AddProperty(mitk::nodeProp_RegEvalTargetContour, mitk::BoolProperty::New(true), renderer, overwrite); + node->AddProperty(mitk::nodeProp_RegEvalWipeStyle, mitk::RegEvalWipeStyleProperty::New(0), renderer, overwrite); + + Superclass::SetDefaultProperties(node, renderer, overwrite); +} + +mitk::RegEvaluationMapper2D::LocalStorage* mitk::RegEvaluationMapper2D::GetLocalStorage(mitk::BaseRenderer* renderer) +{ + return m_LSH.GetLocalStorage(renderer); +} + +void mitk::RegEvaluationMapper2D::TransformActor(mitk::BaseRenderer* renderer) +{ + LocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + //get the transformation matrix of the reslicer in order to render the slice as axial, coronal or saggital + vtkSmartPointer trans = vtkSmartPointer::New(); + vtkSmartPointer matrix = localStorage->m_Reslicer->GetResliceAxes(); + trans->SetMatrix(matrix); + //transform the plane/contour (the actual actor) to the corresponding view (axial, coronal or saggital) + localStorage->m_Actor->SetUserTransform(trans); + //transform the origin to center based coordinates, because MITK is center based. + localStorage->m_Actor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0); + + if ( localStorage->m_Actors->GetNumberOfPaths() > 1 ) + { + vtkActor* secondaryActor = dynamic_cast( localStorage->m_Actors->GetParts()->GetItemAsObject(0) ); + secondaryActor->SetUserTransform(trans); + secondaryActor->SetPosition( -0.5*localStorage->m_mmPerPixel[0], -0.5*localStorage->m_mmPerPixel[1], 0.0); + } +} + +bool mitk::RegEvaluationMapper2D::RenderingGeometryIntersectsImage( const Geometry2D* renderingGeometry, SlicedGeometry3D* imageGeometry ) +{ + // if either one of the two geometries is NULL we return true + // for safety reasons + if ( renderingGeometry == NULL || imageGeometry == NULL ) + return true; + + // get the distance for the first cornerpoint + ScalarType initialDistance = renderingGeometry->SignedDistance( imageGeometry->GetCornerPoint( 0 ) ); + for( int i=1; i<8; i++ ) + { + mitk::Point3D cornerPoint = imageGeometry->GetCornerPoint( i ); + + // get the distance to the other cornerpoints + ScalarType distance = renderingGeometry->SignedDistance( cornerPoint ); + + // if it has not the same signing as the distance of the first point + if ( initialDistance * distance < 0 ) + { + // we have an intersection and return true + return true; + } + } + + // all distances have the same sign, no intersection and we return false + return false; +} + +mitk::RegEvaluationMapper2D::LocalStorage::~LocalStorage() +{ +} + +mitk::RegEvaluationMapper2D::LocalStorage::LocalStorage() +{ + + m_LevelWindowFilter = vtkSmartPointer::New(); + + //Do as much actions as possible in here to avoid double executions. + m_Plane = vtkSmartPointer::New(); + //m_Texture = vtkSmartPointer::New().GetPointer(); + m_Texture = vtkSmartPointer::New().GetPointer(); + m_DefaultLookupTable = vtkSmartPointer::New(); + m_ColorLookupTable = vtkSmartPointer::New(); + m_Mapper = vtkSmartPointer::New(); + m_Actor = vtkSmartPointer::New(); + m_Actors = vtkSmartPointer::New(); + m_Reslicer = mitk::ExtractSliceFilter::New(); + m_EvaluationImage = vtkSmartPointer::New(); + m_EmptyPolyData = vtkSmartPointer::New(); + + mitk::LookupTable::Pointer mitkLUT = mitk::LookupTable::New(); + //built a default lookuptable + mitkLUT->SetType(mitk::LookupTable::GRAYSCALE); + m_DefaultLookupTable = mitkLUT->GetVtkLookupTable(); + + mitkLUT->SetType(mitk::LookupTable::JET); + m_ColorLookupTable = mitkLUT->GetVtkLookupTable(); + + //do not repeat the texture (the image) + m_Texture->RepeatOff(); + + //set the mapper for the actor + m_Actor->SetMapper( m_Mapper ); + + vtkSmartPointer outlineShadowActor = vtkSmartPointer::New(); + outlineShadowActor->SetMapper( m_Mapper ); + + m_Actors->AddPart( outlineShadowActor ); + m_Actors->AddPart( m_Actor ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.h b/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.h new file mode 100644 index 0000000000..6f1fced4e5 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegEvaluationMapper2D.h @@ -0,0 +1,243 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITK_REG_EVALUATION_MAPPER_2D_H +#define MITK_REG_EVALUATION_MAPPER_2D_H + +//MatchPoint +#include +#include "mitkRegEvaluationObject.h" + +//MITK +#include + +//MITK Rendering +#include "mitkBaseRenderer.h" +#include "mitkVtkMapper.h" +#include "mitkExtractSliceFilter.h" + +//VTK +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" + +class vtkActor; +class vtkPolyDataMapper; +class vtkPlaneSource; +class vtkImageData; +class vtkLookupTable; +class vtkImageExtractComponents; +class vtkImageReslice; +class vtkImageChangeInformation; +class vtkPoints; +class vtkMitkThickSlicesFilter; +class vtkPolyData; +class vtkMitkApplyLevelWindowToRGBFilter; +class vtkMitkLevelWindowFilter; + +namespace mitk { + +/** \brief Mapper to resample and display 2D slices of registration evaluation visualization. + * \ingroup Mapper + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegEvaluationMapper2D : public VtkMapper +{ + +public: + /** Standard class typedefs. */ + mitkClassMacro( RegEvaluationMapper2D,VtkMapper ); + + /** Method for creation through the object factory. */ + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + /** \brief Get the target image to map */ + const mitk::Image *GetTargetImage(void); + /** \brief Get the moving image to map */ + const mitk::Image *GetMovingImage(void); + /** \brief Get the target image to map */ + const mitk::MAPRegistrationWrapper *GetRegistration(void); + + /** \brief Checks whether this mapper needs to update itself and generate + * data. */ + virtual void Update(mitk::BaseRenderer * renderer); + + //### methods of MITK-VTK rendering pipeline + virtual vtkProp* GetVtkProp(mitk::BaseRenderer* renderer); + //### end of methods of MITK-VTK rendering pipeline + + /** \brief Internal class holding the mapper, actor, etc. for each of the 3 2D render windows */ + /** + * To render transveral, coronal, and sagittal, the mapper is called three times. + * For performance reasons, the corresponding data for each view is saved in the + * internal helper class LocalStorage. This allows rendering n views with just + * 1 mitkMapper using n vtkMapper. + * */ + class MITKMATCHPOINTREGISTRATION_EXPORT LocalStorage : public mitk::Mapper::BaseLocalStorage + { + public: + /** \brief Actor of a 2D render window. */ + vtkSmartPointer m_Actor; + + vtkSmartPointer m_Actors; + /** \brief Mapper of a 2D render window. */ + vtkSmartPointer m_Mapper; + /** \brief Current slice of a 2D render window.*/ + vtkSmartPointer m_EvaluationImage; + /** \brief Empty vtkPolyData that is set when rendering geometry does not + * intersect the image geometry. + * \warning This member variable is set to NULL, + * if no image geometry is inside the plane geometry + * of the respective render window. Any user of this + * slice has to check whether it is set to NULL! + */ + vtkSmartPointer m_EmptyPolyData; + /** \brief Plane on which the slice is rendered as texture. */ + vtkSmartPointer m_Plane; + /** \brief The texture which is used to render the current slice. */ + vtkSmartPointer m_Texture; + /** \brief The lookuptables for colors and level window */ + vtkSmartPointer m_ColorLookupTable; + vtkSmartPointer m_DefaultLookupTable; + /** \brief The actual reslicer (one per renderer) */ + mitk::ExtractSliceFilter::Pointer m_Reslicer; + + /** part of the target image that is relevant for the rendering*/ + mitk::Image::Pointer m_slicedTargetImage; + /** part of the moving image mapped into the slicedTargetImage + geometry*/ + mitk::Image::Pointer m_slicedMappedImage; + + /** \brief Timestamp of last update of stored data. */ + itk::TimeStamp m_LastUpdateTime; + + /** \brief mmPerPixel relation between pixel and mm. (World spacing).*/ + mitk::ScalarType* m_mmPerPixel; + + /** \brief This filter is used to apply the level window to Grayvalue and RBG(A) images. */ + vtkSmartPointer m_LevelWindowFilter; + + /** \brief Default constructor of the local storage. */ + LocalStorage(); + /** \brief Default deconstructor of the local storage. */ + ~LocalStorage(); + }; + + /** \brief The LocalStorageHandler holds all (three) LocalStorages for the three 2D render windows. */ + mitk::LocalStorageHandler m_LSH; + + /** \brief Get the LocalStorage corresponding to the current renderer. */ + LocalStorage* GetLocalStorage(mitk::BaseRenderer* renderer); + + /** \brief Set the default properties for general image rendering. */ + static void SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer = NULL, bool overwrite = false); + +protected: + /** \brief Transforms the actor to the actual position in 3D. + * \param renderer The current renderer corresponding to the render window. + */ + void TransformActor(mitk::BaseRenderer* renderer); + + /** \brief Generates a plane according to the size of the resliced image in milimeters. + * + * \image html texturedPlane.png + * + * In VTK a vtkPlaneSource is defined through three points. The origin and two + * points defining the axes of the plane (see VTK documentation). The origin is + * set to (xMin; yMin; Z), where xMin and yMin are the minimal bounds of the + * resliced image in space. Z is relevant for blending and the layer property. + * The center of the plane (C) is also the center of the view plane (cf. the image above). + * + * \note For the standard MITK view with three 2D render windows showing three + * different slices, three such planes are generated. All these planes are generated + * in the XY-plane (even if they depict a YZ-slice of the volume). + * + */ + void GeneratePlane(mitk::BaseRenderer* renderer, double planeBounds[6]); + + /** Default constructor */ + RegEvaluationMapper2D(); + /** Default deconstructor */ + virtual ~RegEvaluationMapper2D(); + + /** \brief Does the actual resampling, without rendering the image yet. + * All the data is generated inside this method. The vtkProp (or Actor) + * is filled with content (i.e. the resliced image). + * + * After generation, a 4x4 transformation matrix(t) of the current slice is obtained + * from the vtkResliceImage object via GetReslicesAxis(). This matrix is + * applied to each textured plane (actor->SetUserTransform(t)) to transform everything + * to the actual 3D position (cf. the following image). + * + * \image html cameraPositioning3D.png + * + */ + virtual void GenerateDataForRenderer(mitk::BaseRenderer *renderer); + + void PrepareContour( mitk::DataNode* datanode, LocalStorage * localStorage ); + + void PrepareDifference( LocalStorage * localStorage ); + + void PrepareWipe( mitk::DataNode* datanode, LocalStorage * localStorage ); + + void PrepareCheckerBoard( mitk::DataNode* datanode, LocalStorage * localStorage ); + + void PrepareColorBlend( LocalStorage * localStorage ); + + void PrepareBlend( mitk::DataNode* datanode, LocalStorage * localStorage ); + + /** \brief This method uses the vtkCamera clipping range and the layer property + * to calcualte the depth of the object (e.g. image or contour). The depth is used + * to keep the correct order for the final VTK rendering.*/ + float CalculateLayerDepth(mitk::BaseRenderer* renderer); + + /** \brief This method applies (or modifies) the lookuptable for all types of images. + * \warning To use the lookup table, the property 'Lookup Table' must be set and a 'Image Rendering.Mode' + * which uses the lookup table must be set. +*/ + void ApplyLookuptable(mitk::BaseRenderer* renderer); + + /** + * @brief ApplyLevelWindow Apply the level window for the given renderer. + * \warning To use the level window, the property 'LevelWindow' must be set and a 'Image Rendering.Mode' which uses the level window must be set. + * @param renderer Level window for which renderer? + */ + void ApplyLevelWindow(mitk::BaseRenderer* renderer); + + /** \brief Set the color of the image/polydata */ + void ApplyColor( mitk::BaseRenderer* renderer ); + + /** \brief Set the opacity of the actor. */ + void ApplyOpacity( mitk::BaseRenderer* renderer ); + + /** + * \brief Calculates whether the given rendering geometry intersects the + * given SlicedGeometry3D. + * + * This method checks if the given Geometry2D intersects the given + * SlicedGeometry3D. It calculates the distance of the Geometry2D to all + * 8 cornerpoints of the SlicedGeometry3D. If all distances have the same + * sign (all positive or all negative) there is no intersection. + * If the distances have different sign, there is an intersection. + **/ + bool RenderingGeometryIntersectsImage( const Geometry2D* renderingGeometry, SlicedGeometry3D* imageGeometry ); +}; + +} // namespace mitk + +#endif /* MITKRegEvaluationMapper2D_H_HEADER_INCLUDED_C10E906E */ diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.cpp new file mode 100644 index 0000000000..f9ed48d334 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.cpp @@ -0,0 +1,64 @@ +/*=================================================================== + +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 "mitkRegVisColorStyleProperty.h" + + +mitk::RegVisColorStyleProperty::RegVisColorStyleProperty( ) +{ + AddTypes(); + SetValue( 0 ); +} + + +mitk::RegVisColorStyleProperty::RegVisColorStyleProperty( const IdType& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ) ; + } + else + { + SetValue( 0 ); + } +} + +mitk::RegVisColorStyleProperty::RegVisColorStyleProperty( const std::string& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ); + } + else + { + SetValue( 0 ); + } +} + +void mitk::RegVisColorStyleProperty::AddTypes() +{ + AddEnum( "UniColor", static_cast( 0 ) ); + AddEnum( "VectorMagnitude", static_cast( 1 ) ); +} + + +bool mitk::RegVisColorStyleProperty::AddEnum( const std::string& name, const IdType& id ) +{ + return Superclass::AddEnum( name, id ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.h b/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.h new file mode 100644 index 0000000000..461f0d4c19 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisColorStyleProperty.h @@ -0,0 +1,98 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_VIS_COLOR_STYLE_PROPERTY__H_ +#define _MITK_REG_VIS_COLOR_STYLE_PROPERTY__H_ + +// MITK +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + +/** + * Encapsulates the enumeration for direction for the registration visualization. Valid values are: + * 0/UniColor, 1/VectorMagnitude + * Default is "UniColor" + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegVisColorStyleProperty : public EnumerationProperty +{ +public: + + mitkClassMacro( RegVisColorStyleProperty, EnumerationProperty ); + + itkNewMacro(RegVisColorStyleProperty); + + mitkNewMacro1Param(RegVisColorStyleProperty, const IdType&); + + mitkNewMacro1Param(RegVisColorStyleProperty, const std::string&); + + + using BaseProperty::operator=; + +protected: + + /** + * Constructor. Sets the representation to a default value of 0 + */ + RegVisColorStyleProperty( ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegVisColorStyleProperty( const IdType& value ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegVisColorStyleProperty( const std::string& value ); + + /** + * this function is overridden as protected, so that the user may not add + * additional invalid interpolation types. + */ + virtual bool AddEnum( const std::string& name, const IdType& id ); + + /** + * Adds the enumeration types + */ + virtual void AddTypes(); + +private: + + // purposely not implemented + RegVisColorStyleProperty(const RegVisColorStyleProperty&); + RegVisColorStyleProperty& operator=(const RegVisColorStyleProperty&); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // end of namespace mitk + +#endif diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.cpp new file mode 100644 index 0000000000..524a9e8ea4 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.cpp @@ -0,0 +1,64 @@ +/*=================================================================== + +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 "mitkRegVisDirectionProperty.h" + + +mitk::RegVisDirectionProperty::RegVisDirectionProperty( ) +{ + AddTypes(); + SetValue( 1 ); +} + + +mitk::RegVisDirectionProperty::RegVisDirectionProperty( const IdType& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ) ; + } + else + { + SetValue( 1 ); + } +} + +mitk::RegVisDirectionProperty::RegVisDirectionProperty( const std::string& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ); + } + else + { + SetValue( 1 ); + } +} + +void mitk::RegVisDirectionProperty::AddTypes() +{ + AddEnum( "Direct", static_cast( 0 ) ); + AddEnum( "Inverse", static_cast( 1 ) ); +} + + +bool mitk::RegVisDirectionProperty::AddEnum( const std::string& name, const IdType& id ) +{ + return Superclass::AddEnum( name, id ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.h b/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.h new file mode 100644 index 0000000000..75b6806a02 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisDirectionProperty.h @@ -0,0 +1,98 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_VIS_DIRECTION_PROPERTY__H_ +#define _MITK_REG_VIS_DIRECTION_PROPERTY__H_ + +// MITK +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + +/** + * Encapsulates the enumeration for direction for the registration visualization. Valid values are: + * 0/Direct, 1/Inverse + * Default is "Inverse" + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegVisDirectionProperty : public EnumerationProperty +{ +public: + + mitkClassMacro( RegVisDirectionProperty, EnumerationProperty ); + + itkNewMacro(RegVisDirectionProperty); + + mitkNewMacro1Param(RegVisDirectionProperty, const IdType&); + + mitkNewMacro1Param(RegVisDirectionProperty, const std::string&); + + + using BaseProperty::operator=; + +protected: + + /** + * Constructor. Sets the representation to a default value of 1 + */ + RegVisDirectionProperty( ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 1 + */ + RegVisDirectionProperty( const IdType& value ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 1 + */ + RegVisDirectionProperty( const std::string& value ); + + /** + * this function is overridden as protected, so that the user may not add + * additional invalid interpolation types. + */ + virtual bool AddEnum( const std::string& name, const IdType& id ); + + /** + * Adds the enumeration types + */ + virtual void AddTypes(); + +private: + + // purposely not implemented + RegVisDirectionProperty(const RegVisDirectionProperty&); + RegVisDirectionProperty& operator=(const RegVisDirectionProperty&); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // end of namespace mitk + +#endif diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.cpp new file mode 100644 index 0000000000..ce2728c49e --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.cpp @@ -0,0 +1,393 @@ +/*=================================================================== + +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 +#include +#include +#include +#include +#include +#include + +//MITK +#include + +//MITK +#include "mitkRegVisHelper.h" +#include "mitkRegVisPropertyTags.h" +#include "mitkRegVisDirectionProperty.h" +#include "mitkMAPRegistrationWrapper.h" + +//MAP +#include "mapRegistration.h" + +namespace mitk +{ + + void GetGridGeometryFromNode(const mitk::DataNode* regNode, mitk::Geometry3D::Pointer& gridDesc, unsigned int& gridFrequ) + { + + int internalFrequ = 1; + + if(!regNode->GetIntProperty(mitk::nodeProp_RegVisGridFrequence,internalFrequ)) + { + mitkThrow() << "Cannot configure node correctly. Node property "<GetProperty(valueProp, mitk::nodeProp_RegVisFOVSize)) + { + size = valueProp->GetValue(); + } + else + { + mitkThrow() << "Cannot configure node correctly. Node property "<GetProperty(valueProp, mitk::nodeProp_RegVisFOVSpacing)) + { + spacing = valueProp->GetValue(); + } + else + { + mitkThrow() << "Cannot configure node correctly. Node property "<GetProperty(originProp, mitk::nodeProp_RegVisFOVOrigin)) + { + origin = originProp->GetValue(); + } + else + { + mitkThrow() << "Cannot configure node correctly. Node property "<GetBounds(); + bounds[0] = 0; + bounds[1] = size[0]/spacing[0]; + bounds[2] = 0; + bounds[3] = size[1]/spacing[1]; + bounds[4] = 0; + bounds[5] = size[2]/spacing[2]; + gridDesc->SetBounds(bounds); + gridDesc->SetSpacing(spacing); + gridDesc->SetOrigin(origin); + + gridFrequ = internalFrequ; + } + + + vtkSmartPointer Generate3DDeformationGlyph(const mitk::BaseGeometry* gridDesc, const map::core::RegistrationKernelBase<3,3>* regKernel) + { + assert(gridDesc); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer vectors = vtkSmartPointer::New(); + vectors->SetNumberOfComponents(3); + vectors->SetName("DeformationVectors"); + + long xExtend = itk::Math::Ceil(gridDesc->GetExtent(0)); + long yExtend = itk::Math::Ceil(gridDesc->GetExtent(1)); + long zExtend = itk::Math::Ceil(gridDesc->GetExtent(2)); + long zOffset = xExtend*yExtend; + + mitk::Geometry3D::BoundsArrayType bounds = gridDesc->GetBounds(); + + //Generate Points + mitk::Point3D pos; + for (pos[2] = bounds[4] ; pos[2]< bounds[4]+zExtend; ++(pos[2])) + { + for (pos[1] = bounds[2]; pos[1]< bounds[2]+yExtend; ++(pos[1])) + { + for (pos[0] = bounds[0]; pos[0]< bounds[0]+xExtend; ++(pos[0])) + { + mitk::Point3D worldPos; + gridDesc->IndexToWorld(pos,worldPos); + points->InsertNextPoint(worldPos[0],worldPos[1],worldPos[2]); + + if(regKernel) + { + map::core::RegistrationKernelBase<3,3>::InputPointType regInput(worldPos); + map::core::RegistrationKernelBase<3,3>::OutputPointType regOutput; + + bool mapped = regKernel->mapPoint(regInput,regOutput); + mitk::Vector3D vector(regOutput-regInput); + if (!mapped) + { + vector.Fill(0.0); + } + + vectors->InsertNextTuple(vector.GetDataPointer()); + } + } + } + } + + vtkSmartPointer input = vtkSmartPointer::New(); + vtkSmartPointer vectorMagnitude; + + input->SetPoints(points); + + if(regKernel) + { + input->GetPointData()->SetVectors(vectors); + input->GetPointData()->SetActiveVectors(vectors->GetName()); + + vtkSmartPointer norm = vtkSmartPointer::New(); + norm->SetInputData(input); + norm->SetAttributeModeToUsePointData(); + norm->Update(); + + vectorMagnitude = vtkFloatArray::SafeDownCast(norm->GetOutput()->GetPointData()->GetScalars()); + vectorMagnitude->SetName("VectorMagnitude"); + input->GetPointData()->SetScalars(vectorMagnitude); + input->GetPointData()->SetActiveScalars(vectorMagnitude->GetName()); + } + + vtkSmartPointer glyphFilter = vtkSmartPointer::New(); + glyphFilter->ScalingOn(); + glyphFilter->OrientOn(); + glyphFilter->SetVectorModeToUseVector(); + glyphFilter->SetScaleModeToScaleByVector(); + glyphFilter->SetInputData(input); + + vtkSmartPointer arrowSource = vtkSmartPointer::New(); + arrowSource->SetTipLength(0.2); + + glyphFilter->SetSourceConnection(arrowSource->GetOutputPort()); + + glyphFilter->Update(); + + vtkSmartPointer output = glyphFilter->GetOutput(); + + return output; + } + + vtkSmartPointer MITKMATCHPOINTREGISTRATION_EXPORT Generate3DDeformationGrid( const mitk::BaseGeometry* gridDesc, unsigned int gridFrequence, const map::core::RegistrationKernelBase<3,3>* regKernel /*= NULL*/ ) + { + assert(gridDesc); + + vtkSmartPointer points = vtkSmartPointer::New(); + vtkSmartPointer vectors = vtkSmartPointer::New(); + vectors->SetNumberOfComponents(3); + vectors->SetName("DeformationVectors"); + + long xExtend = itk::Math::Ceil(gridDesc->GetExtent(0))+1; + long yExtend = itk::Math::Ceil(gridDesc->GetExtent(1))+1; + long zExtend = itk::Math::Ceil(gridDesc->GetExtent(2))+1; + long zOffset = xExtend*yExtend; + + mitk::Geometry3D::BoundsArrayType bounds = gridDesc->GetBounds(); + + //Generate Points + mitk::Point3D pos; + for (pos[2] = bounds[4] ; pos[2]< bounds[4]+zExtend; ++(pos[2])) + { + for (pos[1] = bounds[2]; pos[1]< bounds[2]+yExtend; ++(pos[1])) + { + for (pos[0] = bounds[0]; pos[0]< bounds[0]+xExtend; ++(pos[0])) + { + mitk::Point3D worldPos; + gridDesc->IndexToWorld(pos,worldPos); + points->InsertNextPoint(worldPos[0],worldPos[1],worldPos[2]); + + if(regKernel) + { + map::core::RegistrationKernelBase<3,3>::InputPointType regInput(worldPos); + map::core::RegistrationKernelBase<3,3>::OutputPointType regOutput; + + bool mapped = regKernel->mapPoint(regInput,regOutput); + mitk::Vector3D vector(regOutput-regInput); + if (!mapped) + { + vector.Fill(0.0); + } + + vectors->InsertNextTuple(vector.GetDataPointer()); + } + } + } + } + + vtkSmartPointer gridLinesCell = vtkSmartPointer::New(); + vtkSmartPointer gridLine = vtkSmartPointer::New(); + gridLine->GetPointIds()->SetNumberOfIds(2); + + //generate the gridlines between the points + for (long zPos = 0; zPos< zExtend-1; ++zPos) + { + for (long yPos = 0; yPos< yExtend-1; ++yPos) + { + for (long xPos = 0; xPos< xExtend-1; ++xPos) + { + gridLine->GetPointIds()->SetId(0, xPos+yPos*xExtend+zPos*zOffset); + + if ((yPos%gridFrequence == 0) && (zPos%gridFrequence == 0)) + { + gridLine->GetPointIds()->SetId(1, (xPos+1)+yPos*xExtend+zPos*zOffset); + gridLinesCell->InsertNextCell(gridLine); + } + + if ((xPos%gridFrequence == 0) && (zPos%gridFrequence == 0)) + { + gridLine->GetPointIds()->SetId(1, xPos+(yPos+1)*xExtend+zPos*zOffset); + gridLinesCell->InsertNextCell(gridLine); + } + + if ((xPos%gridFrequence == 0) && (yPos%gridFrequence == 0)) + { + gridLine->GetPointIds()->SetId(1, xPos+yPos*xExtend+(zPos+1)*zOffset); + gridLinesCell->InsertNextCell(gridLine); + } + } + } + } + + vtkSmartPointer grid = vtkSmartPointer::New(); + vtkSmartPointer vectorMagnitude; + + grid->SetPoints(points); + grid->SetLines(gridLinesCell); + + if(regKernel) + { + grid->GetPointData()->SetVectors(vectors); + grid->GetPointData()->SetActiveVectors(vectors->GetName()); + + vtkSmartPointer norm = vtkSmartPointer::New(); + norm->SetInputData(grid); + norm->SetAttributeModeToUsePointData(); + norm->Update(); + + vectorMagnitude = vtkFloatArray::SafeDownCast(norm->GetOutput()->GetPointData()->GetScalars()); + vectorMagnitude->SetName("VectorMagnitude"); + } + + vtkSmartPointer input = grid; + + if(regKernel) + { + vtkSmartPointer warp = vtkSmartPointer::New(); + + warp->SetInputData(input); + warp->SetScaleFactor(1); + warp->Update(); + + input = warp->GetPolyDataOutput(); + + input->GetPointData()->SetScalars(vectorMagnitude); + input->GetPointData()->SetActiveScalars(vectorMagnitude->GetName()); + } + + return input; + } + + + bool GridIsOutdated(const mitk::DataNode* regNode, const itk::TimeStamp& reference) + { + + if (PropertyIsOutdated(regNode,mitk::nodeProp_RegVisGridFrequence,reference)) + { + return true; + } + + if (PropertyIsOutdated(regNode,mitk::nodeProp_RegVisFOVSize,reference)) + { + return true; + } + + if (PropertyIsOutdated(regNode,mitk::nodeProp_RegVisFOVSpacing,reference)) + { + return true; + } + + if (PropertyIsOutdated(regNode,mitk::nodeProp_RegVisFOVOrigin,reference)) + { + return true; + } + + if (PropertyIsOutdated(regNode,mitk::nodeProp_RegVisDirection,reference)) + { + return true; + } + + return false; + } + + bool PropertyIsOutdated(const mitk::DataNode* regNode, const std::string& propName, const itk::TimeStamp& reference) + { + if (!regNode) + { + mitkThrow() << "Cannot check for outdated property. Passed regNode is null."; + } + + bool result = false; + + mitk::BaseProperty* prop = regNode->GetProperty(propName.c_str()); + if (prop) + { + result = reference < prop->GetMTime(); + } + else + { + mitkThrow() << "Cannot check for outdated property. Property not defined in passed regNode. Property name: "<* GetRelevantRegKernelOfNode(const mitk::DataNode* regNode) + { + const map::core::RegistrationKernelBase<3,3>* regKernel = NULL; + + if (!regNode) return regKernel; + + const mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast(regNode->GetData()); + + if (!regWrapper) return regKernel; + + const map::core::Registration<3,3>* reg = dynamic_cast*>(regWrapper->GetRegistration()); + + if (reg) + { + mitk::RegVisDirectionProperty* directionProp = NULL; + if (regNode->GetProperty(directionProp, mitk::nodeProp_RegVisDirection)) + { + if (directionProp->GetValueAsId()==0) + { + regKernel = &(reg->getDirectMapping()); + } + else + { + regKernel = &(reg->getInverseMapping()); + } + } + } + return regKernel; + } + +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.h b/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.h new file mode 100644 index 0000000000..de7648916a --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisHelper.h @@ -0,0 +1,83 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_VIS_HELPER__H_ +#define _MITK_REG_VIS_HELPER__H_ + +//VTK +#include +#include + +//MITK +#include +#include + +//MatchPoint +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + + +namespace mitk +{ + +/** Generates the geometry info used to visualized a registration based on the properties + * of the data node containing the registration.\n + * @pre regNode is a correctly initialized data node of a registration + * @param regNode Pointer to the data node of the registration. + * @param [out] gridDesc Smartpointer to the extracted grid geometry. + * @param [out] gridFrequ Grid frequency stored in the regNode. + */ +void MITKMATCHPOINTREGISTRATION_EXPORT GetGridGeometryFromNode(const mitk::DataNode* regNode, mitk::Geometry3D::Pointer& gridDesc, unsigned int& gridFrequ); + +/** + * Generates a 3D defomration gird according to a passed Geometry3D info. It is the basis + * for most of the visualizations of a MatchPoint registration. + */ +vtkSmartPointer MITKMATCHPOINTREGISTRATION_EXPORT Generate3DDeformationGrid(const mitk::BaseGeometry* gridDesc, unsigned int gridFrequence, const map::core::RegistrationKernelBase<3,3>* regKernel = NULL); + +/** + * Generates a 3D glyph representation of the given regKernel in the FOV defined by gridDesc. + */ +vtkSmartPointer MITKMATCHPOINTREGISTRATION_EXPORT Generate3DDeformationGlyph(const mitk::BaseGeometry* gridDesc, const map::core::RegistrationKernelBase<3,3>* regKernel); + +/** + * Checks if the grid relevant node properties are outdated regarding the passed time stamp + * reference*/ +bool MITKMATCHPOINTREGISTRATION_EXPORT GridIsOutdated(const mitk::DataNode* regNode, const itk::TimeStamp& reference); + +/** + * Checks if the property of the passed node is outdated regarding the passed time stamp + * reference + * If the property does not exist the return value indicates if the node is outdated.*/ +bool MITKMATCHPOINTREGISTRATION_EXPORT PropertyIsOutdated(const mitk::DataNode* regNode, const std::string& propName, const itk::TimeStamp& reference); + +/** + * Gets the relevant kernel for visualization of a registration node. The kernel is determined + * by the direction property of the node. + * @return Pointer to the relevant kernel. Method may return NULL if data node is not valid, node + * contains no registration or has no direction property.*/ +MITKMATCHPOINTREGISTRATION_EXPORT const map::core::RegistrationKernelBase<3,3>* GetRelevantRegKernelOfNode(const mitk::DataNode* regNode); + + +} + + +#endif + + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.cpp new file mode 100644 index 0000000000..d613c1a8cf --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.cpp @@ -0,0 +1,35 @@ +/*=================================================================== + +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 "mitkRegVisPropertyTags.h" + + +namespace mitk +{ +// const char* const nodeProp_RegVisGrid = "matchpoint.RegVis.Grid"; +// const char* const nodeProp_RegVisGlyph = "matchpoint.RegVis.Glyph"; +// const char* const nodeProp_RegVisPoints = "matchpoint.RegVis.Points"; +// const char* const nodeProp_RegVisDirection = "matchpoint.RegVis.Direction"; +// const char* const nodeProp_RegVisFOVSize = "matchpoint.RegVis.FOV.size"; +// const char* const nodeProp_RegVisFOVOrigin = "matchpoint.RegVis.FOV.origin"; +// const char* const nodeProp_RegVisFOVSpacing = "matchpoint.RegVis.FOV.spacing"; +// const char* const nodeProp_RegVisGridFrequence = "matchpoint.RegVis.Grid.Frequence"; +// const char* const nodeProp_RegVisGridShowStart = "matchpoint.RegVis.Grid.ShowStart"; +// const char* const nodeProp_RegVisColorStyle = "matchpoint.RegVis.ColorStyle"; +// const char* const nodeProp_RegVisColorUni = "matchpoint.RegVis.UniColor"; +// const char* const nodeProp_RegVisGridStartColor = "matchpoint.RegVis.Grid.StartColor"; +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.h b/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.h new file mode 100644 index 0000000000..83cd3a4791 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisPropertyTags.h @@ -0,0 +1,60 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_VIS_PROPERTY_TAGS__H_ +#define _MITK_REG_VIS_PROPERTY_TAGS__H_ + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ +const char* const nodeProp_RegVisGrid = "matchpoint.RegVis.Grid"; +const char* const nodeProp_RegVisGlyph = "matchpoint.RegVis.Glyph"; +const char* const nodeProp_RegVisPoints = "matchpoint.RegVis.Points"; +const char* const nodeProp_RegVisDirection = "matchpoint.RegVis.Direction"; +const char* const nodeProp_RegVisFOVSize = "matchpoint.RegVis.FOV.size"; +const char* const nodeProp_RegVisFOVOrigin = "matchpoint.RegVis.FOV.origin"; +const char* const nodeProp_RegVisFOVSpacing = "matchpoint.RegVis.FOV.spacing"; +const char* const nodeProp_RegVisFOVOrientation1 = "matchpoint.RegVis.FOV.orientation.row.1"; +const char* const nodeProp_RegVisFOVOrientation2 = "matchpoint.RegVis.FOV.orientation.row.2"; +const char* const nodeProp_RegVisFOVOrientation3 = "matchpoint.RegVis.FOV.orientation.row.3"; +const char* const nodeProp_RegVisGridFrequence = "matchpoint.RegVis.Grid.Frequence"; +const char* const nodeProp_RegVisGridShowStart = "matchpoint.RegVis.Grid.ShowStart"; +const char* const nodeProp_RegVisColorStyle = "matchpoint.RegVis.ColorStyle"; +const char* const nodeProp_RegVisGridStartColor = "matchpoint.RegVis.Grid.StartColor"; +const char* const nodeProp_RegVisColorUni = "matchpoint.RegVis.Color.uni"; +const char* const nodeProp_RegVisColor1Value = "matchpoint.RegVis.Color.1.value"; +const char* const nodeProp_RegVisColor1Magnitude = "matchpoint.RegVis.Color.1.magnitude"; +const char* const nodeProp_RegVisColor2Value = "matchpoint.RegVis.Color.2.value"; +const char* const nodeProp_RegVisColor2Magnitude = "matchpoint.RegVis.Color.2.magnitude"; +const char* const nodeProp_RegVisColor3Value = "matchpoint.RegVis.Color.3.value"; +const char* const nodeProp_RegVisColor3Magnitude = "matchpoint.RegVis.Color.3.magnitude"; +const char* const nodeProp_RegVisColor4Value = "matchpoint.RegVis.Color.4.value"; +const char* const nodeProp_RegVisColor4Magnitude = "matchpoint.RegVis.Color.4.magnitude"; +const char* const nodeProp_RegVisColorInterpolate = "matchpoint.RegVis.ColorInterpolate"; +const char* const nodeProp_RegEvalStyle = "matchpoint.RegEval.Style"; +const char* const nodeProp_RegEvalBlendFactor = "matchpoint.RegEval.BlendFactor"; +const char* const nodeProp_RegEvalCheckerCount = "matchpoint.RegEval.CheckerCount"; +const char* const nodeProp_RegEvalWipeStyle = "matchpoint.RegEval.WipeStyle"; +const char* const nodeProp_RegEvalTargetContour = "matchpoint.RegEval.TargetContour"; +} + + +#endif + + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.cpp new file mode 100644 index 0000000000..2b039df6bf --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.cpp @@ -0,0 +1,65 @@ +/*=================================================================== + +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 "mitkRegVisStyleProperty.h" + + +mitk::RegVisStyleProperty::RegVisStyleProperty( ) +{ + AddTypes(); + SetValue( 0 ); +} + + +mitk::RegVisStyleProperty::RegVisStyleProperty( const IdType& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ) ; + } + else + { + SetValue( 0 ); + } +} + +mitk::RegVisStyleProperty::RegVisStyleProperty( const std::string& value ) +{ + AddTypes(); + if ( IsValidEnumerationValue( value ) ) + { + SetValue( value ); + } + else + { + SetValue( 0 ); + } +} + +void mitk::RegVisStyleProperty::AddTypes() +{ + AddEnum( "Grid", static_cast( 0 ) ); + AddEnum( "Glyph", static_cast( 1 ) ); + AddEnum( "Points", static_cast( 2 ) ); +} + + +bool mitk::RegVisStyleProperty::AddEnum( const std::string& name, const IdType& id ) +{ + return Superclass::AddEnum( name, id ); +} diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.h b/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.h new file mode 100644 index 0000000000..812b4ea5c5 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegVisStyleProperty.h @@ -0,0 +1,100 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_REG_VIS_STYLE_PROPERTY__H_ +#define _MITK_REG_VIS_STYLE_PROPERTY__H_ + +// MITK +#include + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + +/** + * Encapsulates the enumeration for visualization styles. Valid values are: + * 0/Grid, 1/Glyph, 2/Points + * Default is "Grid" + */ +class MITKMATCHPOINTREGISTRATION_EXPORT RegVisStyleProperty : public EnumerationProperty +{ +public: + + mitkClassMacro( RegVisStyleProperty, EnumerationProperty ); + + itkNewMacro(RegVisStyleProperty); + + mitkNewMacro1Param(RegVisStyleProperty, const IdType&); + + mitkNewMacro1Param(RegVisStyleProperty, const std::string&); + + + using BaseProperty::operator=; + +protected: + + /** + * Constructor. Sets the representation to a default value of 0 + */ + RegVisStyleProperty( ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegVisStyleProperty( const IdType& value ); + + /** + * Constructor. Sets the enumeration to the given value. If it is not + * valid, the enumeration is set to 0 + */ + RegVisStyleProperty( const std::string& value ); + + /** + * this function is overridden as protected, so that the user may not add + * additional invalid interpolation types. + */ + virtual bool AddEnum( const std::string& name, const IdType& id ); + + /** + * Adds the enumeration types + */ + virtual void AddTypes(); + +private: + + // purposely not implemented + RegVisStyleProperty(const RegVisStyleProperty&); + RegVisStyleProperty& operator=(const RegVisStyleProperty&); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // end of namespace mitk + +#endif + + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.cpp new file mode 100644 index 0000000000..63a505347b --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.cpp @@ -0,0 +1,77 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include +#include +#include +#include + +#include +#include +#include + +#include "mitkMAPRegistrationWrapper.h" +#include "mitkRegistrationWrapperMapper2D.h" +#include "mitkRegVisHelper.h" + +mitk::MITKRegistrationWrapperMapper2D::MITKRegistrationWrapperMapper2D() +{ + +} + + +mitk::MITKRegistrationWrapperMapper2D::~MITKRegistrationWrapperMapper2D() +{ + +} + +bool mitk::MITKRegistrationWrapperMapper2D::RendererGeometryIsOutdated(mitk::BaseRenderer *renderer, const itk::TimeStamp& time) const +{ + return (time < renderer->GetCurrentWorldGeometry2DUpdateTime()) //was the geometry modified? + || (time < renderer->GetCurrentWorldGeometry2D()->GetMTime()); +} + +bool mitk::MITKRegistrationWrapperMapper2D::GetGeometryDescription( mitk::BaseRenderer *renderer, mitk::BaseGeometry::ConstPointer& gridDesc, unsigned int& gridFrequ ) const +{ + mitk::PlaneGeometry::ConstPointer worldGeometry = renderer->GetCurrentWorldPlaneGeometry(); + + if( ( worldGeometry.IsNull() ) || ( !worldGeometry->IsValid() ) || ( !worldGeometry->HasReferenceGeometry() )) + { + return false; + } + + mitk::PlaneGeometry::Pointer newDesc = worldGeometry->Clone(); + + mitk::Geometry3D::Pointer dummyDesc; + mitk::GetGridGeometryFromNode(this->GetDataNode(), dummyDesc, gridFrequ); + + mitk::Vector3D spacing = worldGeometry->GetSpacing(); + spacing[0] = dummyDesc->GetSpacing()[0]; + spacing[1] = dummyDesc->GetSpacing()[1]; + + mitk::Geometry3D::BoundsArrayType bounds = newDesc->GetBounds(); + bounds[1] *= (newDesc->GetSpacing()[0]/spacing[0]); + bounds[3] *= (newDesc->GetSpacing()[1]/spacing[1]); + newDesc->SetBounds(bounds); + newDesc->SetSpacing(spacing); + + + gridDesc = newDesc; + + return true; +}; + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.h b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.h new file mode 100644 index 0000000000..5e493fc4fe --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper2D.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_2D_H +#define _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_2D_H + + +#include "mitkRegistrationWrapperMapperBase.h" + +#include "MitkMatchPointRegistrationExports.h" + +class vtkPropAssembly; + + +namespace mitk { + +/** Class for the 2D visualization of a registration object.*/ +class MITKMATCHPOINTREGISTRATION_EXPORT MITKRegistrationWrapperMapper2D : public MITKRegistrationWrapperMapperBase +{ +public: + + mitkClassMacro(MITKRegistrationWrapperMapper2D, MITKRegistrationWrapperMapperBase); + itkNewMacro(Self); + + virtual bool GetGeometryDescription(mitk::BaseRenderer *renderer, mitk::BaseGeometry::ConstPointer& gridDesc, unsigned int& gridFrequ) const; + virtual bool RendererGeometryIsOutdated(mitk::BaseRenderer *renderer, const itk::TimeStamp& time) const; + +protected: + + MITKRegistrationWrapperMapper2D(); + virtual ~MITKRegistrationWrapperMapper2D(); + + +private: + +}; + +} // end namespace mitk + + + + +#endif /* MITKRegistrationWrapperMapper2D_H_HEADER_INCLUDED */ + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.cpp new file mode 100644 index 0000000000..c294245eb9 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.cpp @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include +#include +#include +#include + +#include +#include +#include + +#include "mitkMAPRegistrationWrapper.h" +#include "mitkRegistrationWrapperMapper3D.h" +#include "mitkRegVisColorStyleProperty.h" +#include "mitkRegVisHelper.h" +#include "mitkRegVisPropertyTags.h" +#include "mitkRegVisHelper.h" + +mitk::MITKRegistrationWrapperMapper3D::MITKRegistrationWrapperMapper3D() +{ + +} + + +mitk::MITKRegistrationWrapperMapper3D::~MITKRegistrationWrapperMapper3D() +{ + +} + +bool mitk::MITKRegistrationWrapperMapper3D::RendererGeometryIsOutdated(mitk::BaseRenderer *renderer, const itk::TimeStamp& time) const +{ + return false; +} + +bool mitk::MITKRegistrationWrapperMapper3D::GetGeometryDescription(mitk::BaseRenderer *renderer, mitk::BaseGeometry::ConstPointer& gridDesc, unsigned int& gridFrequ) const +{ + mitk::Geometry3D::Pointer newDesc; + mitk::GetGridGeometryFromNode(this->GetDataNode(),newDesc,gridFrequ); + gridDesc = newDesc; + return true; +}; + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.h b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.h new file mode 100644 index 0000000000..c49f42198a --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapper3D.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_3D_H +#define _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_3D_H + + +#include "mitkRegistrationWrapperMapperBase.h" + +#include "MitkMatchPointRegistrationExports.h" + +class vtkPropAssembly; + + +namespace mitk { + +/** Class for the 3D visualization of a registration object.*/ +class MITKMATCHPOINTREGISTRATION_EXPORT MITKRegistrationWrapperMapper3D : public MITKRegistrationWrapperMapperBase +{ +public: + + mitkClassMacro(MITKRegistrationWrapperMapper3D, MITKRegistrationWrapperMapperBase); + itkNewMacro(Self); + + virtual bool GetGeometryDescription(mitk::BaseRenderer *renderer, mitk::BaseGeometry::ConstPointer& gridDesc, unsigned int& gridFrequ) const; + virtual bool RendererGeometryIsOutdated(mitk::BaseRenderer *renderer, const itk::TimeStamp& time) const; + +protected: + + MITKRegistrationWrapperMapper3D(); + virtual ~MITKRegistrationWrapperMapper3D(); + + +private: + +}; + +} // end namespace mitk + + + + +#endif /* MITKRegistrationWrapperMapper3D_H_HEADER_INCLUDED */ + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.cpp b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.cpp new file mode 100644 index 0000000000..6cd3666ec4 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.cpp @@ -0,0 +1,283 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mitkMAPRegistrationWrapper.h" +#include "mitkRegistrationWrapperMapperBase.h" +#include "mitkRegVisColorStyleProperty.h" +#include "mitkRegVisHelper.h" +#include "mitkRegVisPropertyTags.h" + +mitk::MITKRegistrationWrapperMapperBase::MITKRegistrationWrapperMapperBase() +{ + +} + + +mitk::MITKRegistrationWrapperMapperBase::~MITKRegistrationWrapperMapperBase() +{ + +} + +void mitk::MITKRegistrationWrapperMapperBase::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) +{ + if ( !this->IsVisible( renderer ) ) + return; + + RegWrapperLocalStorage *localStorage = m_LSH.GetLocalStorage(renderer); + + //check if updates occured in the node or on the display + const DataNode *node = this->GetDataNode(); + bool outdatedRendererGeometry = RendererGeometryIsOutdated(renderer,localStorage->m_LastUpdateTime); + + if ( (localStorage->m_LastUpdateTime < node->GetMTime()) + || (localStorage->m_LastUpdateTime < node->GetPropertyList()->GetMTime()) //was a property modified? + || (localStorage->m_LastUpdateTime < node->GetPropertyList(renderer)->GetMTime()) + || outdatedRendererGeometry) + { + MITK_DEBUG << "UPDATE NEEDED FOR _ " << renderer->GetName(); + + bool isGridActive = false; + node->GetBoolProperty(mitk::nodeProp_RegVisGrid,isGridActive); + + bool isGlyphActive = false; + node->GetBoolProperty(mitk::nodeProp_RegVisGlyph,isGlyphActive); + + bool isPointsActive = false; + node->GetBoolProperty(mitk::nodeProp_RegVisPoints,isPointsActive); + + bool showStartGrid = false; + node->GetBoolProperty(mitk::nodeProp_RegVisGridShowStart,showStartGrid); + + bool isGridActiveOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisGrid,localStorage->m_LastUpdateTime); + bool isGlyphActiveOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisGlyph,localStorage->m_LastUpdateTime); + bool isPointsActiveOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisPoints,localStorage->m_LastUpdateTime); + bool showStartGridOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisGridShowStart,localStorage->m_LastUpdateTime); + + const mitk::BaseData* baseData = this->GetData(); + if (baseData == NULL) + return; + + const DataNode *node = this->GetDataNode(); + if (node == NULL) + return; + + const mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast(baseData); + if (regWrapper == NULL) + return; + + ////////////////////////////////////////////////////////////////////////// + //1. Check the FOV and presentation styles + bool outdatedFOV = mitk::GridIsOutdated(node,localStorage->m_LastUpdateTime); + if (outdatedFOV ||isGridActiveOutdated || isGlyphActiveOutdated || isPointsActiveOutdated || outdatedRendererGeometry) + { // we need to generate the grids/presentation again + const map::core::RegistrationKernelBase<3,3>* regKernel= mitk::GetRelevantRegKernelOfNode(node); + + if(!regKernel) + { + mitkThrow() << "No reg kernel for visualization"; + } + + mitk::BaseGeometry::ConstPointer gridDesc; + unsigned int gridFrequ =5; + + if (!GetGeometryDescription(renderer,gridDesc, gridFrequ)) + { + return; + }; + + if(isGridActive) + { + localStorage->m_DeformedGridData = mitk::Generate3DDeformationGrid(gridDesc, gridFrequ, regKernel); + localStorage->m_StartGridData = mitk::Generate3DDeformationGrid(gridDesc,gridFrequ); + localStorage->m_DeformedGridMapper->SetInputData(localStorage->m_DeformedGridData); + localStorage->m_StartGridMapper->SetInputData(localStorage->m_StartGridData); + } + else if (isGlyphActive) + { + localStorage->m_DeformedGridData = mitk::Generate3DDeformationGlyph(gridDesc, regKernel); + localStorage->m_StartGridData = NULL; + localStorage->m_DeformedGridMapper->SetInputData(localStorage->m_DeformedGridData); + } + else + { + mitkThrow() << "No reg kernel visualization style activated."; + } + } + + ////////////////////////////////////////////////////////////////////////// + //2.Check if the mappers or actors must be modified + bool isColorStyleOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColorStyle,localStorage->m_LastUpdateTime); + bool isColorUniOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColorUni,localStorage->m_LastUpdateTime); + bool isColor1Outdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor1Value,localStorage->m_LastUpdateTime); + bool isColor2Outdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor2Value,localStorage->m_LastUpdateTime); + bool isColor3Outdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor3Value,localStorage->m_LastUpdateTime); + bool isColor4Outdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor4Value,localStorage->m_LastUpdateTime); + bool isColor2MagOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor2Magnitude,localStorage->m_LastUpdateTime); + bool isColor3MagOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor3Magnitude,localStorage->m_LastUpdateTime); + bool isColor4MagOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColor4Magnitude,localStorage->m_LastUpdateTime); + bool isColorInterpolateOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisColorInterpolate,localStorage->m_LastUpdateTime); + + if(isColorStyleOutdated || isColorUniOutdated || isColor1Outdated || + isColor2Outdated || isColor2MagOutdated || isColor3Outdated || isColor3MagOutdated || + isColor4Outdated || isColor4MagOutdated || isColorInterpolateOutdated) + { + localStorage->m_DeformedGridMapper->ScalarVisibilityOn(); + localStorage->m_DeformedGridMapper->SetScalarModeToUsePointData(); + localStorage->m_DeformedGridMapper->SelectColorArray( "VectorMagnitude" ); + + mitk::RegVisColorStyleProperty* colorStyleProp = NULL; + node->GetProperty(colorStyleProp, mitk::nodeProp_RegVisColorStyle); + + float color1[3] = {0.0,0.0,0.0}; + node->GetColor( color1, NULL, mitk::nodeProp_RegVisColor1Value ); + float color2[3] = {0.25,0.25,0.25}; + node->GetColor( color2, NULL, mitk::nodeProp_RegVisColor2Value ); + float color3[3] = {0.5,0.5,0.5}; + node->GetColor( color3, NULL, mitk::nodeProp_RegVisColor3Value ); + float color4[3] = {1.0,1.0,1.0}; + node->GetColor( color4, NULL, mitk::nodeProp_RegVisColor4Value ); + + double mag2 = 0; + node->GetPropertyValue(mitk::nodeProp_RegVisColor2Magnitude, mag2); + double mag3 = 0; + node->GetPropertyValue(mitk::nodeProp_RegVisColor3Magnitude, mag3); + double mag4 = 0; + node->GetPropertyValue(mitk::nodeProp_RegVisColor4Magnitude, mag4); + + bool interpolate = true; + node->GetBoolProperty(mitk::nodeProp_RegVisColorInterpolate,interpolate); + + //default :color by vector magnitude + localStorage->m_DeformedGridMapper->SelectColorArray( "VectorMagnitude" ); + localStorage->m_DeformedGridMapper->SetUseLookupTableScalarRange(true); + + localStorage->m_LUT = vtkSmartPointer::New(); + + if (!colorStyleProp || colorStyleProp->GetValueAsId()==0) + { //uni color mode + float temprgb[3] = {1.0,1.0,1.0}; + node->GetColor( temprgb, NULL, mitk::nodeProp_RegVisColorUni ); + localStorage->m_LUT->AddRGBSegment(0.0,temprgb[0],temprgb[1],temprgb[2],1.0,temprgb[0],temprgb[1],temprgb[2]); + localStorage->m_LUT->Build(); + localStorage->m_DeformedGridMapper->SetLookupTable(localStorage->m_LUT); + } + else + { + localStorage->m_LUT->AddRGBPoint(0.0,color1[0],color1[1],color1[2]); + localStorage->m_LUT->AddRGBPoint(mag2,color2[0],color2[1],color2[2]); + localStorage->m_LUT->AddRGBPoint(mag3,color3[0],color3[1],color3[2]); + localStorage->m_LUT->AddRGBPoint(mag4,color4[0],color4[1],color4[2]); + if (!interpolate) + { + localStorage->m_LUT->AddRGBPoint(0.99*mag2,color1[0],color1[1],color1[2]); + localStorage->m_LUT->AddRGBPoint(0.99*mag3,color2[0],color2[1],color2[2]); + localStorage->m_LUT->AddRGBPoint(0.99*mag4,color3[0],color3[1],color3[2]); + }; + } + + localStorage->m_LUT->Build(); + localStorage->m_DeformedGridMapper->SetLookupTable(localStorage->m_LUT); + localStorage->m_DeformedGridMapper->Update(); + } + + bool isGridStartColorOutdated = mitk::PropertyIsOutdated(node,mitk::nodeProp_RegVisGridStartColor,localStorage->m_LastUpdateTime); + + if(isGridStartColorOutdated) + { + localStorage->m_StartGridMapper->ScalarVisibilityOn(); + localStorage->m_StartGridMapper->SetScalarModeToUsePointFieldData(); + + float temprgb[3]; + if (node->GetColor( temprgb, NULL, mitk::nodeProp_RegVisGridStartColor )) + { + double trgb[3] = { (double) temprgb[0], (double) temprgb[1], (double) temprgb[2] }; + localStorage->m_StartGridActor->GetProperty()->SetColor(trgb); + } + } + + ////////////////////////////////////////////////////////////////////////// + //3. Check if Assembly must be updated + if(isGridActiveOutdated||isGlyphActiveOutdated||isPointsActiveOutdated||showStartGridOutdated) + { + localStorage->m_RegAssembly = vtkSmartPointer::New(); + + if (isGridActive) + { + localStorage->m_RegAssembly->AddPart(localStorage->m_DeformedGridActor); + if (showStartGrid) + { + localStorage->m_RegAssembly->AddPart(localStorage->m_StartGridActor); + } + } + else if (isGlyphActive) + { + localStorage->m_RegAssembly->AddPart(localStorage->m_DeformedGridActor); + } + } + + localStorage->m_LastUpdateTime.Modified(); + + } +} + + +void mitk::MITKRegistrationWrapperMapperBase::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) +{ + Superclass::SetDefaultProperties(node, renderer, overwrite); +} + +vtkProp* mitk::MITKRegistrationWrapperMapperBase::GetVtkProp(mitk::BaseRenderer *renderer) +{ + return m_LSH.GetLocalStorage(renderer)->m_RegAssembly; +} + +void mitk::MITKRegistrationWrapperMapperBase::SetVtkMapperImmediateModeRendering(vtkMapper *) +{ + +} + +mitk::MITKRegistrationWrapperMapperBase::RegWrapperLocalStorage::RegWrapperLocalStorage() +{ + m_DeformedGridActor = vtkSmartPointer::New(); + m_DeformedGridMapper = vtkSmartPointer::New(); + m_DeformedGridActor->SetMapper(m_DeformedGridMapper); + + m_StartGridActor = vtkSmartPointer::New(); + m_StartGridMapper = vtkSmartPointer::New(); + m_StartGridActor->SetMapper(m_StartGridMapper); + + m_RegAssembly = vtkSmartPointer::New(); + + m_LUT = vtkSmartPointer::New(); + + m_DeformedGridData = NULL; + m_StartGridData = NULL; +} + diff --git a/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.h b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.h new file mode 100644 index 0000000000..6ff5354f41 --- /dev/null +++ b/Modules/MatchPointRegistration/Rendering/mitkRegistrationWrapperMapperBase.h @@ -0,0 +1,101 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_BASE_H +#define _MITK_MITK_REGISTRATION_WRAPPER_MAPPER_BASE_H + + +#include + +#include +#include + +#include "MitkMatchPointRegistrationExports.h" + +class vtkPropAssembly; +class vtkPolyDataMapper; +class vtkPolyData; +class vtkColorTransferFunction; +class vtkActor; + +namespace mitk { + +/**Base class for all mapper that visualize a registration object.*/ +class MITKRegistrationWrapperMapperBase : public VtkMapper +{ +public: + + mitkClassMacro(MITKRegistrationWrapperMapperBase, VtkMapper); + + //========== essential implementation for mapper ========== + virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); + static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); + static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); + virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); + //========================================================= + + virtual bool GetGeometryDescription(mitk::BaseRenderer *renderer, mitk::BaseGeometry::ConstPointer& gridDesc, unsigned int& gridFrequ) const = 0; + virtual bool RendererGeometryIsOutdated(mitk::BaseRenderer *renderer, const itk::TimeStamp& time) const = 0; + + /**Internal class to store all informations and helper needed by a mapper to provide the render data for a + certain renderer.*/ + class MITKMATCHPOINTREGISTRATION_EXPORT RegWrapperLocalStorage : public mitk::Mapper::BaseLocalStorage + { + public: + vtkSmartPointer m_DeformedGridData; + vtkSmartPointer m_StartGridData; + + vtkSmartPointer m_DeformedGridActor; + vtkSmartPointer m_DeformedGridMapper; + vtkSmartPointer m_StartGridActor; + vtkSmartPointer m_StartGridMapper; + + vtkSmartPointer m_RegAssembly; + + vtkSmartPointer m_LUT; + + /** \brief Timestamp of last update of stored data. */ + itk::TimeStamp m_LastUpdateTime; + /** \brief Constructor of the local storage. Do as much actions as possible in here to avoid double executions. */ + RegWrapperLocalStorage(); + + ~RegWrapperLocalStorage() + { + } + }; + + /** \brief This member holds all three LocalStorages for the 3D render window(s). */ + mitk::LocalStorageHandler m_LSH; + + +protected: + + MITKRegistrationWrapperMapperBase(); + virtual ~MITKRegistrationWrapperMapperBase(); + + +private: + +}; + +} // end namespace mitk + + + + +#endif /* MITKRegistrationWrapperMapperBase_H_HEADER_INCLUDED */ + diff --git a/Modules/MatchPointRegistration/Testing/CMakeLists.txt b/Modules/MatchPointRegistration/Testing/CMakeLists.txt new file mode 100644 index 0000000000..d45daf111d --- /dev/null +++ b/Modules/MatchPointRegistration/Testing/CMakeLists.txt @@ -0,0 +1 @@ +MITK_CREATE_MODULE_TESTS() \ No newline at end of file diff --git a/Modules/MatchPointRegistration/Testing/files.cmake b/Modules/MatchPointRegistration/Testing/files.cmake new file mode 100644 index 0000000000..5efdc15458 --- /dev/null +++ b/Modules/MatchPointRegistration/Testing/files.cmake @@ -0,0 +1,3 @@ +SET(MODULE_TESTS + mitkTimeFramesRegistrationHelperTest.cpp +) \ No newline at end of file diff --git a/Modules/MatchPointRegistration/Testing/mitkTimeFramesRegistrationHelperTest.cpp b/Modules/MatchPointRegistration/Testing/mitkTimeFramesRegistrationHelperTest.cpp new file mode 100644 index 0000000000..ff665949c4 --- /dev/null +++ b/Modules/MatchPointRegistration/Testing/mitkTimeFramesRegistrationHelperTest.cpp @@ -0,0 +1,111 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkTestingMacros.h" +#include "mitkTestFixture.h" + +#include "mitkTimeFramesRegistrationHelper.h" + +class mitkTimeFramesRegistrationHelperTestSuite : public mitk::TestFixture +{ + CPPUNIT_TEST_SUITE(mitkTimeFramesRegistrationHelperTestSuite); + // Test the append method + MITK_TEST(SetAllowUndefPixels_GetAllowUndefPixels); + MITK_TEST(SetPaddingValue_GetPaddingValue); + MITK_TEST(SetErrorValue_GetErrorValue); + MITK_TEST(SetAllowUnregPixels_GetAllowUnregPixels); + MITK_TEST(SetInterpolatorType_GetInterpolatorType); + MITK_TEST(Set_Get_Clear_IgnoreList); + CPPUNIT_TEST_SUITE_END(); +private: + mitk::TimeFramesRegistrationHelper::Pointer frameRegHelper; + mitk::TimeFramesRegistrationHelper::IgnoreListType ignoreList; + +public: + void setUp() override + { + frameRegHelper = mitk::TimeFramesRegistrationHelper::New(); + ignoreList.clear(); + ignoreList.push_back(2); + ignoreList.push_back(13); + } + + void tearDown() override + { + } + + void SetAllowUndefPixels_GetAllowUndefPixels() + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on default value", true, + frameRegHelper->GetAllowUndefPixels()); + frameRegHelper->SetAllowUndefPixels(false); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on changed value", false, + frameRegHelper->GetAllowUndefPixels()); + } + + void SetPaddingValue_GetPaddingValue() + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on default value", 0.0, + frameRegHelper->GetPaddingValue()); + frameRegHelper->SetPaddingValue(11); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on changed value", 11.0, + frameRegHelper->GetPaddingValue()); + } + + void SetAllowUnregPixels_GetAllowUnregPixels() + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on default value", true, + frameRegHelper->GetAllowUnregPixels()); + frameRegHelper->SetAllowUnregPixels(false); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on changed value", false, + frameRegHelper->GetAllowUnregPixels()); + } + + void SetErrorValue_GetErrorValue() + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on default value", 0.0, frameRegHelper->GetErrorValue()); + frameRegHelper->SetErrorValue(15); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on changed value", 15.0, + frameRegHelper->GetErrorValue()); + } + + void SetInterpolatorType_GetInterpolatorType() + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on default value", mitk::ImageMappingInterpolator::Linear, + frameRegHelper->GetInterpolatorType()); + frameRegHelper->SetInterpolatorType(mitk::ImageMappingInterpolator::NearestNeighbor); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Check getter on changed value", + mitk::ImageMappingInterpolator::NearestNeighbor, frameRegHelper->GetInterpolatorType()); + } + + void Set_Get_Clear_IgnoreList() + { + CPPUNIT_ASSERT(frameRegHelper->GetIgnoreList().empty()); + + itk::ModifiedTimeType mtime = frameRegHelper->GetMTime(); + frameRegHelper->SetIgnoreList(ignoreList); + CPPUNIT_ASSERT(mtime < frameRegHelper->GetMTime()); + CPPUNIT_ASSERT(ignoreList == frameRegHelper->GetIgnoreList()); + + mtime = frameRegHelper->GetMTime(); + frameRegHelper->ClearIgnoreList(); + CPPUNIT_ASSERT(mtime < frameRegHelper->GetMTime()); + CPPUNIT_ASSERT(frameRegHelper->GetIgnoreList().empty()); + } + +}; + +MITK_TEST_SUITE_REGISTRATION(mitkTimeFramesRegistrationHelper) \ No newline at end of file diff --git a/Modules/MatchPointRegistration/algorithms/CMakeLists.txt b/Modules/MatchPointRegistration/algorithms/CMakeLists.txt new file mode 100644 index 0000000000..87723f283b --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/CMakeLists.txt @@ -0,0 +1,7 @@ +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_MultiModal_affine_default CPP_FILES mitkMultiModalAffine_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_MultiModal_rigid_default CPP_FILES mitkMultiModalRigid_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_MultiModal_translation_default CPP_FILES mitkMultiModalTrans_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_Rigid_closedform_points_default CPP_FILES mitkRigidClosedFormPoints_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_Rigid_ICP_default CPP_FILES mitkRigidICP_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_FastSymmetricForcesDemons_MultiRes_default CPP_FILES mitkFastSymmetricForcesDemonsMultiRes_default.cpp) +mitkFunctionCreateMatchPointDeployedAlgorithm(NAME MITK_LevelSetMotion_MultiRes_default CPP_FILES mitkLevelSetMotionMultiRes_default.cpp) diff --git a/Modules/MatchPointRegistration/algorithms/MITK_FastSymmetricForcesDemons_MultiRes_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_FastSymmetricForcesDemons_MultiRes_default.profile new file mode 100644 index 0000000000..824fc58bcb --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_FastSymmetricForcesDemons_MultiRes_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "Demons.FastSymmetricForces.3D.multiRes.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "This algorithm is a default option for monomodal deformable problem statements in DIPP. The registration algorithm is based on the concept of Thiron's demons using fast symmetric forces and using a 4 level multi resolution approach to get faster and more robust results.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") +SET(ALGORITHM_PROFILE_Citation "Tom Vercauteren, Xavier Pennec, Aymeric Perchant, and Nicholas Ayache. Diffeomorphic Demons Using ITK's Finite Difference Solver Hierarchy. Insight Journal , ISC/NA-MIC Workshop on Open Science at MICCAI 2007, October 2007.") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_ResolutionStyle "4 (multi res)") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any/monomodal") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any/monomodal") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "deformable") +SET(ALGORITHM_PROFILE_TransformDomain "local") +SET(ALGORITHM_PROFILE_Metric "Mean square difference") +SET(ALGORITHM_PROFILE_Keywords "deformable" "demons" "monomodal" "multi resolution" "DIR" "NRR") diff --git a/Modules/MatchPointRegistration/algorithms/MITK_LevelSetMotion_MultiRes_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_LevelSetMotion_MultiRes_default.profile new file mode 100644 index 0000000000..2697ae130b --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_LevelSetMotion_MultiRes_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "LevelSetMotion.3D.multiRes.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "This algorithm is an default option for monomodal deformable problem statements in DIPP. Deformable 3D registration algorithm based on an level set motion approach and using a 4 level multi resolution approach to get faster and more robust results. This algorithm is only suitable for mono modal tasks.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") +SET(ALGORITHM_PROFILE_Citation "B.C. Vemuri, J. Ye, Y. Chen, C.M. Leonard.: Image registration via level-set motion: applications to atlas-based segmentation. Medical Image Analysis. Vol. 7. pp. 1-20. 2003.") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_ResolutionStyle "4 (multi res)") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any/monomodal") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any/monomodal") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "deformable") +SET(ALGORITHM_PROFILE_TransformDomain "lokal") +SET(ALGORITHM_PROFILE_Metric "Mean square difference") +SET(ALGORITHM_PROFILE_Keywords "deformable" "monomodal" "multi resolution" "DIR" "NRR") diff --git a/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_affine_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_affine_default.profile new file mode 100644 index 0000000000..16dd2e3ac8 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_affine_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "MultiModal.affine.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "Algorithm is used as default solution for multimodal affine 3D (translation, rotation, scaling, shearing) problem statements in DIPP. Uses 3 Resolution levels. By default initializes via image centers.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_ResolutionStyle "3 (multi res)") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "affine") +SET(ALGORITHM_PROFILE_Metric "Mattes mutual information") +SET(ALGORITHM_PROFILE_TransformDomain "global") +SET(ALGORITHM_PROFILE_Optimization "Regular Step Gradient Descent") +SET(ALGORITHM_PROFILE_Keywords "basic" "pre initialization" "multimodal" "affine" "generic" "multipurpose") diff --git a/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_rigid_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_rigid_default.profile new file mode 100644 index 0000000000..61d6a52725 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_rigid_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "MultiModal.rigid.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "Algorithm is used as default solution for multimodal rigid problem statements in DIPP. Uses 3 Resolution levels. By default initializes via image centers.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_ResolutionStyle "3 (multi res)") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "rigid") +SET(ALGORITHM_PROFILE_Metric "Mattes mutual information") +SET(ALGORITHM_PROFILE_TransformDomain "global") +SET(ALGORITHM_PROFILE_Optimization "Regular Step Gradient Descent") +SET(ALGORITHM_PROFILE_Keywords "basic" "pre initialization" "multimodal" "rigid" "generic" "multipurpose") diff --git a/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_translation_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_translation_default.profile new file mode 100644 index 0000000000..8329073ab5 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_MultiModal_translation_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "MultiModal.translation.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.1") + +SET(ALGORITHM_PROFILE_Description "Algorithm is used as default solution for multimodal problem statements in DIPP where only translation is needed. Uses 3 Resolution levels. By default initializes via image centers.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") + +SET(ALGORITHM_PROFILE_DataType "Image") +SET(ALGORITHM_PROFILE_ResolutionStyle "3 (multi res)") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "translation") +SET(ALGORITHM_PROFILE_Metric "Mattes mutual information") +SET(ALGORITHM_PROFILE_TransformDomain "global") +SET(ALGORITHM_PROFILE_Optimization "Regular Step Gradient Descent") +SET(ALGORITHM_PROFILE_Keywords "basic" "pre initialization" "translation" "multimodal") diff --git a/Modules/MatchPointRegistration/algorithms/MITK_Rigid_ICP_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_Rigid_ICP_default.profile new file mode 100644 index 0000000000..1371452033 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_Rigid_ICP_default.profile @@ -0,0 +1,21 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "RigidICP.3D.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "Simple 3D rigid (translation and euler angles) registration algorithm using point sets and the iterative closesed points scheme. It tries to minimize the minimal point distance errors (no point paires are assumed). Remark: at least 6 points per point sets are needed; the number must not equal.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") +SET(ALGORITHM_PROFILE_Citation "P.J. Besl, N.D. McKay.: A Method for Registration of 3-D Shapes. IEEE Trans. on Pattern Analysis and Machine Intelligence. Vol. 14 2. pp. 239-256. 1992. doi:10.1109/34.121791.") + +SET(ALGORITHM_PROFILE_DataType "Points") +SET(ALGORITHM_PROFILE_ResolutionStyle "Single") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "rigid") +SET(ALGORITHM_PROFILE_TransformDomain "global") +SET(ALGORITHM_PROFILE_ComputationStyle "iterative") +SET(ALGORITHM_PROFILE_Deterministic "1") +SET(ALGORITHM_PROFILE_Keywords "basic" "point sets" "ICP" "rigid") \ No newline at end of file diff --git a/Modules/MatchPointRegistration/algorithms/MITK_Rigid_closedform_points_default.profile b/Modules/MatchPointRegistration/algorithms/MITK_Rigid_closedform_points_default.profile new file mode 100644 index 0000000000..f9104757be --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/MITK_Rigid_closedform_points_default.profile @@ -0,0 +1,20 @@ +SET(ALGORITHM_PROFILE_UID_Namespace "org.mitk") +SET(ALGORITHM_PROFILE_UID_Name "RigidClosedForm.3D.default") +SET(ALGORITHM_PROFILE_UID_Version "1.0.0") + +SET(ALGORITHM_PROFILE_Description "Simple 3D rigid (translation and euler angles) registration algorithm using point sets pairs and a closed form solution. It assumes that both given point sets are sorted by pair index.") +SET(ALGORITHM_PROFILE_Contact "Ralf Floca\; mitk-users@lists.sourceforge.net") + +SET(ALGORITHM_PROFILE_DataType "Points") +SET(ALGORITHM_PROFILE_ResolutionStyle "Single") +SET(ALGORITHM_PROFILE_DimMoving "3") +SET(ALGORITHM_PROFILE_ModalityMoving "any") +SET(ALGORITHM_PROFILE_DimTarget "3") +SET(ALGORITHM_PROFILE_ModalityTarget "any") +SET(ALGORITHM_PROFILE_Subject "any") +SET(ALGORITHM_PROFILE_Object "any") +SET(ALGORITHM_PROFILE_TransformModel "rigid") +SET(ALGORITHM_PROFILE_TransformDomain "global") +SET(ALGORITHM_PROFILE_ComputationStyle "analytic") +SET(ALGORITHM_PROFILE_Deterministic "1") +SET(ALGORITHM_PROFILE_Keywords "basic" "point sets" "point pair" "rigid") diff --git a/Modules/MatchPointRegistration/algorithms/mitkFastSymmetricForcesDemonsMultiRes_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkFastSymmetricForcesDemonsMultiRes_default.cpp new file mode 100644 index 0000000000..d48fd75983 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkFastSymmetricForcesDemonsMultiRes_default.cpp @@ -0,0 +1,27 @@ +/*=================================================================== + +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 "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapITKFastSymmetricForcesDemonsMultiResRegistrationAlgorithm.h" +#include "mapConfigure.h" + +#include "MITK_FastSymmetricForcesDemons_MultiRes_default_ProfileResource.h" +typedef map::core::discrete::Elements<3>::InternalImageType ImageType; +typedef map::algorithm::boxed::ITKFastSymmetricForcesDemonsMultiResRegistrationAlgorithm +AlgorithmType; + +mapDeployAlgorithmMacro(AlgorithmType); diff --git a/Modules/MatchPointRegistration/algorithms/mitkLevelSetMotionMultiRes_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkLevelSetMotionMultiRes_default.cpp new file mode 100644 index 0000000000..663c52a5ba --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkLevelSetMotionMultiRes_default.cpp @@ -0,0 +1,27 @@ +/*=================================================================== + +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 "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapITKLevelSetMotionMultiResRegistrationAlgorithm.h" +#include "mapConfigure.h" + +#include "MITK_LevelSetMotion_MultiRes_default_ProfileResource.h" +typedef map::core::discrete::Elements<3>::InternalImageType ImageType; +typedef map::algorithm::boxed::ITKLevelSetMotionMultiResRegistrationAlgorithm +AlgorithmType; + +mapDeployAlgorithmMacro(AlgorithmType); diff --git a/Modules/MatchPointRegistration/algorithms/mitkMultiModalAffine_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkMultiModalAffine_default.cpp new file mode 100644 index 0000000000..3ce44ebb61 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkMultiModalAffine_default.cpp @@ -0,0 +1,136 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapITKAffineMattesMIMultiResRegistrationAlgorithmTemplate.h" +#include "mapConfigure.h" + +#include "MITK_MultiModal_affine_default_ProfileResource.h" + +namespace mitk +{ + typedef map::core::discrete::Elements<3>::InternalImageType ImageType; + + /** \class MultiModalAffineDefaultRegistrationAlgorithm + * Algorithm is used as default solution for multimodal affine problem statements in DIPP. + * Uses 3 Resolution levels. By default initializes via image centers + */ + class MultiModalAffineDefaultRegistrationAlgorithm : + public map::algorithm::boxed::ITKAffineMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + { + public: + typedef MultiModalAffineDefaultRegistrationAlgorithm Self; + + typedef ITKAffineMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + Superclass; + + typedef ::itk::SmartPointer Pointer; + typedef ::itk::SmartPointer ConstPointer; + + itkTypeMacro(MultiModalAffineDefaultRegistrationAlgorithm, + ITKAffineMattesMIMultiResRegistrationAlgorithm); + mapNewAlgorithmMacro(Self); + + protected: + MultiModalAffineDefaultRegistrationAlgorithm() + { + }; + + virtual ~MultiModalAffineDefaultRegistrationAlgorithm() + { + }; + + void configureAlgorithm() + { + Superclass::configureAlgorithm(); + + this->setResolutionLevels(3); + this->_preInitialize = true; + this->_useCenterOfGravity = false; + + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMaximumStepLength(3.00); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMinimumStepLength(0.5); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetNumberOfIterations(200); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetRelaxationFactor(0.8); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetGradientMagnitudeTolerance(1e-4); + + //metric + this->getConcreteMetricControl()->getConcreteMetric()->SetNumberOfHistogramBins(30); + this->getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(true); + this->getConcreteMetricControl()->getConcreteMetric()->ReinitializeSeed(); + this->getConcreteMetricControl()->getConcreteMetric()->UseExplicitPDFDerivativesOn(); + } + + void + doInterLevelSetup() + { + Superclass::doInterLevelSetup(); + + //scale setting + int dimCount = ImageType::ImageDimension*ImageType::ImageDimension + ImageType::ImageDimension; + int matrixEnd = ImageType::ImageDimension*ImageType::ImageDimension; + Superclass::ConcreteOptimizerType::ScalesType scales(dimCount); + double matrixScale = 1.0; + double transScale = 1.0; + + if (this->getCurrentLevel() == 0) + { + matrixScale = 10.0; + transScale = 1.0 / 10000; + } + else + { + matrixScale = 1.0; + transScale = 1.0 / 1000; + } + + for (int i = 0; i < dimCount; ++i) + { + if (i < matrixEnd) + { + scales[i] = matrixScale; + + } + else + { + scales[i] = transScale; + } + } + + getConcreteOptimizerControl()->getConcreteOptimizer()->SetScales(scales); + + //spatial samples setting + if (this->getCurrentLevel() != 0) + { + getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(false); + + unsigned int nrOfSmpl = ::itk::Math::Round + (this->getMovingImage()->GetLargestPossibleRegion().GetNumberOfPixels() * 0.30); + + getConcreteMetricControl()->getConcreteMetric()->SetNumberOfSpatialSamples(nrOfSmpl); + } + }; + + private: + + MultiModalAffineDefaultRegistrationAlgorithm(const Self& source); //purposely not implemented + void operator=(const Self&); //purposely not implemented + }; + +} + +mapDeployAlgorithmMacro(mitk::MultiModalAffineDefaultRegistrationAlgorithm); diff --git a/Modules/MatchPointRegistration/algorithms/mitkMultiModalRigid_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkMultiModalRigid_default.cpp new file mode 100644 index 0000000000..e6d8b697f1 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkMultiModalRigid_default.cpp @@ -0,0 +1,133 @@ +/*=================================================================== + +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 "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapITKEuler3DMattesMIMultiResRegistrationAlgorithmTemplate.h" +#include "mapConfigure.h" + +#include "MITK_MultiModal_rigid_default_ProfileResource.h" + +namespace mitk +{ + typedef map::core::discrete::Elements<3>::InternalImageType ImageType; + + /** \class MultiModalRigidDefaultRegistrationAlgorithm + * Algorithm is used as default solution for multimodal rigid problem statements in DIPP. + * Uses 3 Resolution levels. By default initializes via image centers + */ + class MultiModalRigidDefaultRegistrationAlgorithm : + public map::algorithm::boxed::ITKEuler3DMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + { + public: + typedef MultiModalRigidDefaultRegistrationAlgorithm Self; + + typedef ITKEuler3DMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + Superclass; + + typedef ::itk::SmartPointer Pointer; + typedef ::itk::SmartPointer ConstPointer; + + itkTypeMacro(MultiModalRigidDefaultRegistrationAlgorithm, + ITKEuler3DMattesMIMultiResRegistrationAlgorithm); + mapNewAlgorithmMacro(Self); + + protected: + MultiModalRigidDefaultRegistrationAlgorithm() + { + }; + + virtual ~MultiModalRigidDefaultRegistrationAlgorithm() + { + }; + + void configureAlgorithm() + { + Superclass::configureAlgorithm(); + + this->setResolutionLevels(3); + this->_preInitialize = true; + this->_useCenterOfGravity = false; + + //optimizer + ConcreteOptimizerType::ScalesType scales(6); + scales[0] = 1.0; + scales[1] = 1.0; + scales[2] = 1.0; + scales[3] = 1.0 / 1000; + scales[4] = 1.0 / 1000; + scales[5] = 1.0 / 1000; + + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetScales(scales); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMaximumStepLength(3.00); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMinimumStepLength(0.5); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetNumberOfIterations(200); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetRelaxationFactor(0.8); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetGradientMagnitudeTolerance(1e-4); + + //metric + this->getConcreteMetricControl()->getConcreteMetric()->SetNumberOfHistogramBins(30); + this->getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(true); + this->getConcreteMetricControl()->getConcreteMetric()->ReinitializeSeed(); + this->getConcreteMetricControl()->getConcreteMetric()->UseExplicitPDFDerivativesOn(); + } + + void + doInterLevelSetup() + { + Superclass::doInterLevelSetup(); + + if (this->getCurrentLevel() == 0) + { + OptimizerBaseType::SVNLOptimizerBaseType::ScalesType scales(6); + scales[0] = 10.0; + scales[1] = 10.0; + scales[2] = 10.0; + scales[3] = 1.0 / 10000; + scales[4] = 1.0 / 10000; + scales[5] = 1.0 / 10000; + getConcreteOptimizerControl()->getConcreteOptimizer()->SetScales(scales); + } + else + { + getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(false); + + OptimizerBaseType::SVNLOptimizerBaseType::ScalesType scales(6); + scales[0] = 1.0; + scales[1] = 1.0; + scales[2] = 1.0; + scales[3] = 1.0 / 1000; + scales[4] = 1.0 / 1000; + scales[5] = 1.0 / 1000; + + getConcreteOptimizerControl()->getConcreteOptimizer()->SetScales(scales); + + unsigned int nrOfSmpl = ::itk::Math::Round + (this->getMovingImage()->GetLargestPossibleRegion().GetNumberOfPixels() * 0.15); + + getConcreteMetricControl()->getConcreteMetric()->SetNumberOfSpatialSamples(nrOfSmpl); + } + }; + + private: + + MultiModalRigidDefaultRegistrationAlgorithm(const Self& source); //purposely not implemented + void operator=(const Self&); //purposely not implemented + }; + +} + +mapDeployAlgorithmMacro(mitk::MultiModalRigidDefaultRegistrationAlgorithm); diff --git a/Modules/MatchPointRegistration/algorithms/mitkMultiModalTrans_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkMultiModalTrans_default.cpp new file mode 100644 index 0000000000..4cc0bea6b3 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkMultiModalTrans_default.cpp @@ -0,0 +1,109 @@ +/*=================================================================== + +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 "mapDeploymentDLLHelper.h" +#include "mapDiscreteElements.h" +#include "mapITKTransMattesMIMultiResRegistrationAlgorithm.h" +#include "mapConfigure.h" + +#include "MITK_MultiModal_translation_default_ProfileResource.h" + +namespace mitk +{ + typedef map::core::discrete::Elements<3>::InternalImageType ImageType; + + /** \class MultiModalTranslationDefaultRegistrationAlgorithm + * Algorithm is used as default solution for multimodal 3-degrees of freedom (translation) problem statements in DIPP. + * Uses 3 Resolution levels. By default initializes via image centers + */ + class MultiModalTranslationDefaultRegistrationAlgorithm : + public map::algorithm::boxed::ITKTransMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + { + public: + typedef MultiModalTranslationDefaultRegistrationAlgorithm Self; + + typedef ITKTransMattesMIMultiResRegistrationAlgorithm >, map::algorithm::itk::NoComponentInitializationPolicy> + Superclass; + + typedef ::itk::SmartPointer Pointer; + typedef ::itk::SmartPointer ConstPointer; + + itkTypeMacro(MultiModalTranslationDefaultRegistrationAlgorithm, + ITKEuler3DMattesMIMultiResRegistrationAlgorithm); + mapNewAlgorithmMacro(Self); + + protected: + MultiModalTranslationDefaultRegistrationAlgorithm() + { + }; + + virtual ~MultiModalTranslationDefaultRegistrationAlgorithm() + { + }; + + void configureAlgorithm() + { + Superclass::configureAlgorithm(); + + this->setResolutionLevels(3); + this->_preInitialize = true; + this->_useCenterOfGravity = false; + + //optimizer + ConcreteOptimizerType::ScalesType scales(3); + scales[0] = 1.0; + scales[1] = 1.0; + scales[2] = 1.0; + + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetScales(scales); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMaximumStepLength(3.00); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetMinimumStepLength(0.5); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetNumberOfIterations(200); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetRelaxationFactor(0.8); + this->getConcreteOptimizerControl()->getConcreteOptimizer()->SetGradientMagnitudeTolerance(1e-4); + + //metric + this->getConcreteMetricControl()->getConcreteMetric()->SetNumberOfHistogramBins(30); + this->getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(true); + this->getConcreteMetricControl()->getConcreteMetric()->ReinitializeSeed(); + this->getConcreteMetricControl()->getConcreteMetric()->UseExplicitPDFDerivativesOn(); + } + + void + doInterLevelSetup() + { + Superclass::doInterLevelSetup(); + + if (this->getCurrentLevel() != 0) + { + getConcreteMetricControl()->getConcreteMetric()->SetUseAllPixels(false); + + unsigned int nrOfSmpl = ::itk::Math::Round + (this->getMovingImage()->GetLargestPossibleRegion().GetNumberOfPixels() * 0.15); + + getConcreteMetricControl()->getConcreteMetric()->SetNumberOfSpatialSamples(nrOfSmpl); + } + }; + + private: + + MultiModalTranslationDefaultRegistrationAlgorithm(const Self& source); //purposely not implemented + void operator=(const Self&); //purposely not implemented + }; + +} + +mapDeployAlgorithmMacro( mitk::MultiModalTranslationDefaultRegistrationAlgorithm); diff --git a/Modules/MatchPointRegistration/algorithms/mitkRigidClosedFormPoints_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkRigidClosedFormPoints_default.cpp new file mode 100644 index 0000000000..fa80e5ce3a --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkRigidClosedFormPoints_default.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mapDeploymentDLLHelper.h" +#include "mapContinuousElements.h" +#include "mapITKRigid3DClosedFormRegistrationAlgorithmTemplate.h" +#include "mapConfigure.h" + +#include "MITK_Rigid_closedform_points_default_ProfileResource.h" + +typedef map::core::continuous::Elements<3>::InternalPointSetType PointSetType; +typedef map::algorithm::boxed::ITKRigid3DClosedFormRegistrationAlgorithmTemplate::Type +AlgorithmType; + +mapDeployAlgorithmMacro(AlgorithmType); diff --git a/Modules/MatchPointRegistration/algorithms/mitkRigidICP_default.cpp b/Modules/MatchPointRegistration/algorithms/mitkRigidICP_default.cpp new file mode 100644 index 0000000000..1d85122eb1 --- /dev/null +++ b/Modules/MatchPointRegistration/algorithms/mitkRigidICP_default.cpp @@ -0,0 +1,27 @@ +/*=================================================================== + +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 "mapDeploymentDLLHelper.h" +#include "mapContinuousElements.h" +#include "mapITKRigid3DICPRegistrationAlgorithmTemplate.h" +#include "mapConfigure.h" + +#include "MITK_Rigid_ICP_default_ProfileResource.h" + +typedef map::core::continuous::Elements<3>::InternalPointSetType PointSetType; +typedef map::algorithm::boxed::ITKRigid3DICPRegistrationAlgorithm AlgorithmType; + +mapDeployAlgorithmMacro(AlgorithmType); diff --git a/Modules/MatchPointRegistration/autoload/IO/CMakeLists.txt b/Modules/MatchPointRegistration/autoload/IO/CMakeLists.txt new file mode 100644 index 0000000000..0881f2493b --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/CMakeLists.txt @@ -0,0 +1,7 @@ +MITK_CREATE_MODULE(MatchPointRegistrationIO + DEPENDS + PUBLIC MitkMatchPointRegistration MitkSceneSerializationBase + PACKAGE_DEPENDS + PRIVATE ITK MatchPoint + AUTOLOAD_WITH MitkCore +) diff --git a/Modules/MatchPointRegistration/autoload/IO/files.cmake b/Modules/MatchPointRegistration/autoload/IO/files.cmake new file mode 100644 index 0000000000..e56b5a7dfe --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/files.cmake @@ -0,0 +1,16 @@ +set(CPP_FILES + mitkMatchPointActivator.cpp + mitkMAPRegistrationWrapperIO.cpp + mitkMAPRegistrationWrapperSerializer.cpp +) + +set(H_FILES + mitkMAPRegistrationWrapperIO.h + mitkMAPRegistrationWrapperSerializer.h +) + +set(TPP_FILES +) + +set(MOC_H_FILES +) diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp new file mode 100644 index 0000000000..56329ec574 --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp @@ -0,0 +1,319 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include + +#include + +#include "mapRegistration.h" +#include "mapRegistrationFileWriter.h" +#include "mapRegistrationFileReader.h" +#include "mapLazyFileFieldKernelLoader.h" + +#include +#include + +#include "mitkMAPRegistrationWrapperIO.h" +#include "mitkMAPRegistrationWrapper.h" + +namespace mitk +{ + + /** Helper structure to change (and reset) the + * local settings in a function scope*/ + struct LocaleSwitch + { + LocaleSwitch(const std::string& newLocale) + : m_OldLocale(std::setlocale(LC_ALL, NULL)) + , m_NewLocale(newLocale) + { + if (m_OldLocale == NULL) + { + m_OldLocale = ""; + } + else if (m_NewLocale != m_OldLocale) + { + // set the locale + if (std::setlocale(LC_ALL, m_NewLocale.c_str()) == NULL) + { + MITK_INFO << "Could not set locale " << m_NewLocale; + m_OldLocale = NULL; + } + } + } + + ~LocaleSwitch() + { + if (m_OldLocale != NULL && std::setlocale(LC_ALL, m_OldLocale) == NULL) + { + MITK_INFO << "Could not reset locale " << m_OldLocale; + } + } + + private: + const char* m_OldLocale; + const std::string m_NewLocale; + }; + + /** Helper class that allows to use an functor in multiple combinations of + * moving and target dimensions on a passed MAPRegistrationWrapper instance.\n + * DimHelperSub is used DimHelper to iterate in a row of the dimension + * combination matrix. + */ + template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor> + class DimHelperSub + { + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) + { + if (TFunctor::Execute(obj, data)) + { + return true; + } + return DimHelperSub::Execute(obj, data); + } + }; + + /** Specialized template version of DimSubHelper that indicates the end + * of the row in the dimension combination matrix, thus does nothing. + */ + template< unsigned int i, template < unsigned int, unsigned int> class TFunctor> + class DimHelperSub + { + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) + { + //just unwind. Go to the next "row" with DimHelper + return false; + } + }; + + /** Helper class that allows to use an functor in multiple combinations of + * moving and target dimensions on a passed MAPRegistrationWrapper instance.\n + * It is helpful if you want to ensure that all combinations are checked/touched + * (e.g. 3D 3D, 3D 2D, 2D 3D, 2D 2D) without generating a large switch yard. + * Think of n*m matrix (indicating the posible combinations). DimHelper walks from + * one row to the next and uses DimHelperSub to iterate in a row.\n + * For every element of the matrix the functor is executed on the passed object. + */ + template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor> + class DimHelper{ + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data = "") + { + if (DimHelperSub::Execute(obj, data)) + { + return true; + } + return DimHelper::Execute(obj, data); + } + }; + + /** Specialized template version of DimHelper that indicates the end + * of the dimension combination matrix, thus does nothing. + */ + template< unsigned int j, template < unsigned int, unsigned int> class TFunctor> + class DimHelper<1,j, TFunctor > + { + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) + { + //just unwind. We are done. + return false; + } + }; + + /** Functor that checks of the dimension of the registration is supported and can + * be written. + */ + template + class CanWrite + { + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data = "") + { + bool result = false; + + result = dynamic_cast *>(obj->GetRegistration()) != NULL; + + return result; + } + }; + + /** Functor that writes the registration to a file if it has the right dimensionality. + */ + template + class WriteReg + { + public: + static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) + { + const map::core::Registration* pReg = dynamic_cast*>(obj->GetRegistration()); + if (pReg == NULL) + { + return false; + } + + typedef map::io::RegistrationFileWriter WriterType; + typename WriterType::Pointer writer = WriterType::New(); + + writer->setExpandLazyKernels(false); + + try + { + writer->write(pReg,data); + } + catch (itk::ExceptionObject e) + { + std::cout << e << std::endl; + throw; + } + + return true; + } + }; + + MAPRegistrationWrapperIO::MAPRegistrationWrapperIO(const MAPRegistrationWrapperIO& other) + : AbstractFileIO(other) + { + } + + MAPRegistrationWrapperIO::MAPRegistrationWrapperIO() : AbstractFileIO(mitk::MAPRegistrationWrapper::GetStaticNameOfClass()) + { + std::string category = "MatchPoint Registration File"; + CustomMimeType customMimeType; + customMimeType.SetCategory(category); + customMimeType.AddExtension("mapr"); + this->AbstractFileIOWriter::SetMimeType(customMimeType); + this->AbstractFileIOWriter::SetDescription(category); + + customMimeType.AddExtension("mapr.xml"); + customMimeType.AddExtension("MAPR"); + customMimeType.AddExtension("MAPR.XML"); + this->AbstractFileIOReader::SetMimeType(customMimeType); + this->AbstractFileIOReader::SetDescription(category); + + this->RegisterService(); + } + + + void MAPRegistrationWrapperIO::Write() + { + bool success = false; + const BaseData* input = this->GetInput(); + if (input == NULL) + { + mitkThrow() << "Cannot write data. Data pointer is NULL."; + } + + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast(input); + if (wrapper == NULL) + { + mitkThrow() << "Cannot write data. Data pointer is not a Registration wrapper."; + } + + std::ostream* writeStream = this->GetOutputStream(); + std::string fileName = this->GetOutputLocation(); + if (writeStream) + { + fileName = this->GetLocalFileName(); + } + + // Switch the current locale to "C" + LocaleSwitch localeSwitch("C"); + + try + { + success = DimHelper<3,3,WriteReg>::Execute(wrapper, fileName); + } + catch (const std::exception& e) + { + mitkThrow() << e.what(); + } + + if (!success) + { + mitkThrow() << "Cannot write registration. Currently only registrations up to 4D are supported."; + } + } + + AbstractFileIO::ConfidenceLevel MAPRegistrationWrapperIO::GetWriterConfidenceLevel() const + { + const mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast(this->GetInput()); + + if (regWrapper == NULL) + { + return IFileWriter::Unsupported; + } + + // Check if the registration dimension is supported + if (! DimHelper<3,3,CanWrite>::Execute(regWrapper)) + { + return IFileWriter::Unsupported; + }; + + return IFileWriter::Supported; + } + + std::vector MAPRegistrationWrapperIO::Read() + { + std::vector result; + + LocaleSwitch("C"); + + std::string fileName = this->GetLocalFileName(); + if ( fileName.empty() ) + { + mitkThrow() << "Cannot read file. Filename has not been set!"; + } + + /* Remove the following kernel loader provider because in MITK no lazy file loading should be used + due to conflicts with session loading (end there usage of temporary directories)*/ + map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<2,2>::getStaticProviderName()); + map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<3,3>::getStaticProviderName()); + + map::io::RegistrationFileReader::Pointer spReader = map::io::RegistrationFileReader::New(); + spReader->setPreferLazyLoading(true); + map::core::RegistrationBase::Pointer spReg = spReader->read(fileName); + mitk::MAPRegistrationWrapper::Pointer spRegWrapper = mitk::MAPRegistrationWrapper::New(); + spRegWrapper->SetRegistration(spReg); + + result.push_back(spRegWrapper.GetPointer()); + return result; + } + + AbstractFileIO::ConfidenceLevel MAPRegistrationWrapperIO::GetReaderConfidenceLevel() const + { + AbstractFileIO::ConfidenceLevel result = IFileReader::Unsupported; + + std::string fileName = this->GetLocalFileName(); + std::ifstream in( fileName.c_str() ); + if ( in.good() ) + { + result = IFileReader::Supported; + } + + in.close(); + return result; + } + + MAPRegistrationWrapperIO* MAPRegistrationWrapperIO::IOClone() const + { + return new MAPRegistrationWrapperIO(*this); + } + +} diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.h b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.h new file mode 100644 index 0000000000..153cde2780 --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.h @@ -0,0 +1,53 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_MAP_REGISTRATION_WRAPPER_IO_H +#define _MITK_MAP_REGISTRATION_WRAPPER_IO_H + +#include + +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + /** + * Offers IO capability for MatchPoint registration wrappers + */ + class MAPRegistrationWrapperIO : public AbstractFileIO + { + public: + + MAPRegistrationWrapperIO(); + + // -------------- AbstractFileReader ------------- + using AbstractFileReader::Read; + virtual std::vector > Read(); + + virtual ConfidenceLevel GetReaderConfidenceLevel() const; + + // -------------- AbstractFileWriter ------------- + virtual void Write(); + virtual ConfidenceLevel GetWriterConfidenceLevel() const; + + private: + MAPRegistrationWrapperIO(const MAPRegistrationWrapperIO& other); + MAPRegistrationWrapperIO* IOClone() const; + }; + + +} // end of namespace mitk + +#endif diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.cpp b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.cpp new file mode 100644 index 0000000000..6c26c4096a --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.cpp @@ -0,0 +1,75 @@ +/*=================================================================== + +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 "mitkMAPRegistrationWrapperSerializer.h" +#include "mitkMAPRegistrationWrapperIO.h" + +#include "mitkMAPRegistrationWrapper.h" + +#include + + +MITK_REGISTER_SERIALIZER(MAPRegistrationWrapperSerializer) + + +mitk::MAPRegistrationWrapperSerializer::MAPRegistrationWrapperSerializer() +{ +} + + +mitk::MAPRegistrationWrapperSerializer::~MAPRegistrationWrapperSerializer() +{ +} + + +std::string mitk::MAPRegistrationWrapperSerializer::Serialize() +{ + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast( m_Data.GetPointer() ); + if (wrapper == NULL) + { + MITK_ERROR << " Object at " << (const void*) this->m_Data + << " is not an mitk::MAPRegistrationWrapper. Cannot serialize as MAPRegistrationWrapper for MatchPoint registration objects."; + return ""; + } + + std::string filename( this->GetUniqueFilenameInWorkingDirectory() ); + filename += "_"; + filename += m_FilenameHint; + filename += ".mapr"; + + std::string fullname(m_WorkingDirectory); + fullname += "/"; + fullname += itksys::SystemTools::ConvertToOutputPath(filename.c_str()); + + try + { + MAPRegistrationWrapperIO writer; + writer.SetOutputLocation(fullname); + writer.AbstractFileWriter::SetInput( const_cast( wrapper ) ); + writer.Write(); + } + catch (std::exception& e) + { + MITK_ERROR << " Error serializing object at " << (const void*) this->m_Data + << " to " + << fullname + << ": " + << e.what(); + return ""; + } + return filename; +} diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.h b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.h new file mode 100644 index 0000000000..5fe8e41bb1 --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperSerializer.h @@ -0,0 +1,42 @@ +/*=================================================================== + +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 __mitkMAPRegistrationWrapperSerializer_h +#define __mitkMAPRegistrationWrapperSerializer_h + +#include + +namespace mitk +{ +/** + \brief Serializes mitk::MAPRegistrationWrapper for mitk::SceneIO +*/ +class MAPRegistrationWrapperSerializer : public BaseDataSerializer +{ + public: + mitkClassMacro( MAPRegistrationWrapperSerializer, BaseDataSerializer ); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + virtual std::string Serialize(); + + protected: + MAPRegistrationWrapperSerializer(); + virtual ~MAPRegistrationWrapperSerializer(); +}; +} // namespace +#endif diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMatchPointActivator.cpp b/Modules/MatchPointRegistration/autoload/IO/mitkMatchPointActivator.cpp new file mode 100644 index 0000000000..90b3841279 --- /dev/null +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMatchPointActivator.cpp @@ -0,0 +1,48 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkMAPRegistrationWrapperIO.h" + +#include +#include + + +namespace mitk { + +/* + * This is the module activator for the "MatchPoint" module. + */ +class MatchPointActivator : public us::ModuleActivator +{ +public: + + void Load(us::ModuleContext* context) + { + m_MAPRegistrationWrapperIO = new MAPRegistrationWrapperIO(); + } + + void Unload(us::ModuleContext* ) + { + delete m_MAPRegistrationWrapperIO; + } + +private: + + mitk::MAPRegistrationWrapperIO* m_MAPRegistrationWrapperIO; +}; +} + +US_EXPORT_MODULE_ACTIVATOR(mitk::MatchPointActivator) diff --git a/Modules/MatchPointRegistration/files.cmake b/Modules/MatchPointRegistration/files.cmake new file mode 100644 index 0000000000..d38d4a6dd3 --- /dev/null +++ b/Modules/MatchPointRegistration/files.cmake @@ -0,0 +1,58 @@ +set(CPP_FILES + mitkMAPRegistrationWrapper.cpp + mitkMAPRegistrationWrapperObjectFactory.cpp + mitkRegEvaluationObjectFactory.cpp + mitkRegEvaluationObject.cpp + Helper/mitkUIDHelper.cpp + Helper/mitkAlgorithmHelper.cpp + Helper/mitkMaskedAlgorithmHelper.cpp + Helper/mitkRegistrationHelper.cpp + Helper/mitkImageMappingHelper.cpp + Helper/mitkPointSetMappingHelper.cpp + Helper/mitkResultNodeGenerationHelper.cpp + Helper/mitkTimeFramesRegistrationHelper.cpp + Rendering/mitkRegistrationWrapperMapper2D.cpp + Rendering/mitkRegistrationWrapperMapper3D.cpp + Rendering/mitkRegistrationWrapperMapperBase.cpp + Rendering/mitkRegEvaluationMapper2D.cpp + Rendering/mitkRegVisStyleProperty.cpp + Rendering/mitkRegVisDirectionProperty.cpp + Rendering/mitkRegVisColorStyleProperty.cpp + Rendering/mitkRegVisPropertyTags.cpp + Rendering/mitkRegVisHelper.cpp + Rendering/mitkRegEvalStyleProperty.cpp + Rendering/mitkRegEvalWipeStyleProperty.cpp +) + +set(H_FILES + mitkMatchPointPropertyTags.h + mitkMAPRegistrationWrapper.h + mitkMAPRegistrationWrapperObjectFactory.h + mitkRegEvaluationObjectFactory.h + mitkRegEvaluationObject.h + Helper/mitkUIDHelper.h + Helper/mitkAlgorithmHelper.h + Helper/mitkMaskedAlgorithmHelper.h + Helper/mitkRegistrationHelper.h + Helper/mitkImageMappingHelper.h + Helper/mitkPointSetMappingHelper.h + Helper/mitkResultNodeGenerationHelper.h + Helper/mitkTimeFramesRegistrationHelper.h + Rendering/mitkRegistrationWrapperMapper2D.h + Rendering/mitkRegistrationWrapperMapper3D.h + Rendering/mitkRegistrationWrapperMapperBase.h + Rendering/mitkRegVisStyleProperty.h + Rendering/mitkRegVisDirectionProperty.h + Rendering/mitkRegVisColorStyleProperty.h + Rendering/mitkRegVisPropertyTags.h + Rendering/mitkRegVisHelper.h + Rendering/mitkRegEvaluationMapper2D.h + Rendering/mitkRegEvalStyleProperty.h + Rendering/mitkRegEvalWipeStyleProperty.h +) + +set(TPP_FILES +) + +set(MOC_H_FILES +) diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.cpp b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.cpp new file mode 100644 index 0000000000..a821cc0528 --- /dev/null +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.cpp @@ -0,0 +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 "mitkMAPRegistrationWrapper.h" + +#include + +mitk::MAPRegistrationWrapper::MAPRegistrationWrapper() +{ +} + +mitk::MAPRegistrationWrapper::~MAPRegistrationWrapper() +{ +} + +void mitk::MAPRegistrationWrapper::SetRequestedRegionToLargestPossibleRegion() +{ + //nothing to do +} + +bool mitk::MAPRegistrationWrapper::RequestedRegionIsOutsideOfTheBufferedRegion() +{ + return false; +} + +bool mitk::MAPRegistrationWrapper::VerifyRequestedRegion() +{ + return true; +} + +void mitk::MAPRegistrationWrapper::SetRequestedRegion(const itk::DataObject*) +{ + //nothing to do +} + +unsigned int mitk::MAPRegistrationWrapper::GetMovingDimensions() const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot return moving dimension. Wrapper points to invalid registration (NULL)."; + } + return m_spRegistration->getMovingDimensions(); +} + + +unsigned int mitk::MAPRegistrationWrapper::GetTargetDimensions() const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot return target dimension. Wrapper points to invalid registration (NULL)."; + } + return m_spRegistration->getTargetDimensions(); +} + +const mitk::MAPRegistrationWrapper::TagMapType& mitk::MAPRegistrationWrapper::GetTags() const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot return registration tags. Wrapper points to invalid registration (NULL)."; + } + return m_spRegistration->getTags(); +} + +bool mitk::MAPRegistrationWrapper::GetTagValue(const TagType & tag, ValueType & value) const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot return registration tag value. Wrapper points to invalid registration (NULL). Tag: " << tag; + } + return m_spRegistration->getTagValue(tag,value); +} + +bool mitk::MAPRegistrationWrapper::HasLimitedTargetRepresentation() const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot determin HasLimitedTargetRepresentation(). Wrapper points to invalid registration (NULL)."; + } + return m_spRegistration->hasLimitedTargetRepresentation(); +} + +bool mitk::MAPRegistrationWrapper::HasLimitedMovingRepresentation() const +{ + if (m_spRegistration.IsNull()) + { + mitkThrow()<< "Error. Cannot determin HasLimitedMovingRepresentation(). Wrapper points to invalid registration (NULL)."; + } + return m_spRegistration->hasLimitedMovingRepresentation(); +} + +map::core::RegistrationBase* mitk::MAPRegistrationWrapper::GetRegistration() +{ + return m_spRegistration; +} + +const map::core::RegistrationBase* mitk::MAPRegistrationWrapper::GetRegistration() const +{ + return m_spRegistration; +} + +void mitk::MAPRegistrationWrapper::SetRegistration(map::core::RegistrationBase* pReg) +{ + m_spRegistration = pReg; +} + +void mitk::MAPRegistrationWrapper::PrintSelf (std::ostream &os, itk::Indent indent) const +{ + Superclass::PrintSelf(os,indent); + if (m_spRegistration.IsNull()) + { + os<< "Error. Wrapper points to invalid registration (NULL)."; + } + else + { + os<Print(os,indent.GetNextIndent()); + + typedef map::core::Registration<3,3> CastedRegType; + const CastedRegType* pCastedReg = dynamic_cast(m_spRegistration.GetPointer()); + + os<getDirectMapping().Print(os,indent.GetNextIndent()); + + os<getInverseMapping().Print(os,indent.GetNextIndent()); + + } +} diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.h b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.h new file mode 100644 index 0000000000..23b62015eb --- /dev/null +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapper.h @@ -0,0 +1,276 @@ +/*=================================================================== + +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 mitkMAPRegistrationWrapper_h +#define mitkMAPRegistrationWrapper_h + +//MITK +#include +#include + +//MatchPoint +#include +#include +#include +#include + +//MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ +/*! + \brief MAPRegistrationWrapper + Wrapper class to allow the handling of MatchPoint registration objects as mitk data (e.g. in the data explorer). +*/ +class MITKMATCHPOINTREGISTRATION_EXPORT MAPRegistrationWrapper: public mitk::BaseData +{ +public: + + mitkClassMacro( MAPRegistrationWrapper, BaseData ); + + itkNewMacro( Self ); + + /** + * Empty implementation, since the MAPRegistrationWrapper doesn't + * support the requested region concept + */ + virtual void SetRequestedRegionToLargestPossibleRegion(); + + /** + * Empty implementation, since the MAPRegistrationWrapper doesn't + * support the requested region concept + */ + virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); + + /** + * Empty implementation, since the MAPRegistrationWrapper doesn't + * support the requested region concept + */ + virtual bool VerifyRequestedRegion(); + + /** + * Empty implementation, since the MAPRegistrationWrapper doesn't + * support the requested region concept + */ + virtual void SetRequestedRegion(const itk::DataObject*); + + /*! @brief Gets the number of moving dimensions + @pre valid registration instance must be set. + */ + virtual unsigned int GetMovingDimensions() const; + + /*! @brief Gets the number of target dimensions + @pre valid registration instance must be set. + */ + virtual unsigned int GetTargetDimensions() const; + + /*! typedefs used for the TagMap + */ + typedef ::map::core::RegistrationBase::TagType TagType; + typedef ::map::core::RegistrationBase::ValueType ValueType; + typedef ::map::core::RegistrationBase::TagMapType TagMapType; + + /*! @brief returns the tags associated with this registration + @pre valid registration instance must be set. + @return a TagMapType containing tags + */ + const TagMapType& GetTags() const; + + /*! @brief returns the tag value for a specific tag + @pre valid registration instance must be set. + @return the success of the operation + */ + bool GetTagValue(const TagType & tag, ValueType & value) const; + + /*! Indicates + @pre valid registration instance must be set. + @return is the target representation limited + @retval true if target representation is limited. Thus it is not guaranteed that all inverse mapping operations + will succeed. Transformation(inverse kernel) covers only a part of the target space). + @retval false if target representation is not limited. Thus it is guaranteed that all inverse mapping operations + will succeed. + */ + bool HasLimitedTargetRepresentation() const; + + /*! + @pre valid registration instance must be set. + @return is the moving representation limited + @retval true if moving representation is limited. Thus it is not guaranteed that all direct mapping operations + will succeed. Transformation(direct kernel) covers only a part of the moving space). + @retval false if moving representation is not limited. Thus it is guaranteed that all direct mapping operations + will succeed. + */ + bool HasLimitedMovingRepresentation() const; + + /*! Helper function that maps a mitk point (of arbitrary dimension) from moving space to target space. + @remarks The operation might fail, if the moving and target dimension of the registration + is not equal to the dimensionality of the passed points. + @pre valid registration instance must be set. + @param inPoint Reference pointer to a MovingPointType + @param outPoint pointer to a TargetPointType + @return success of operation. + @pre direct mapping kernel must be defined + */ + template + bool MapPoint(const ::itk::Point& inPoint, ::itk::Point& outPoint) const + { + typedef ::itk::Point MITKMovingPointType; + typedef ::itk::Point MITKTargetPointType; + typedef typename ::map::core::continuous::Elements::PointType MAPMovingPointType; + typedef typename ::map::core::continuous::Elements::PointType MAPTargetPointType; + + if (m_spRegistration.IsNull()) + { + mapDefaultExceptionMacro(<< "Error. Cannot map point. Wrapper points to invalid registration (NULL). Point: " << inPoint); + } + + bool result = false; + + if ((this->GetMovingDimensions() == VMovingDim)&&(this->GetTargetDimensions() == VTargetDim)) + { + MAPMovingPointType tempInP; + MAPTargetPointType tempOutP; + tempInP.CastFrom(inPoint); + + typedef map::core::Registration CastedRegType; + const CastedRegType* pCastedReg = dynamic_cast(m_spRegistration.GetPointer()); + + if (!pCastedReg) + { + mapDefaultExceptionMacro(<< "Error. Cannot map point. Registration has invalid dimension. Point: " << inPoint); + } + + result = pCastedReg->mapPoint(tempInP,tempOutP); + if (result) + { + outPoint.CastFrom(tempOutP); + } + + } + + return result; + }; + + /*! Helper function that maps a mitk point (of arbitrary dimension) from target space to moving space + @remarks The operation might faile, if the moving and target dimension of the registration + is not equal to the dimensionalities of the passed points. + @pre valid registration instance must be set. + @param inPoint pointer to a TargetPointType + @param outPoint pointer to a MovingPointType + @return success of operation + */ + template + bool MapPointInverse(const ::itk::Point & inPoint, ::itk::Point & outPoint) const +{ + typedef ::itk::Point MITKMovingPointType; + typedef ::itk::Point MITKTargetPointType; + typedef typename ::map::core::continuous::Elements::PointType MAPMovingPointType; + typedef typename ::map::core::continuous::Elements::PointType MAPTargetPointType; + + if (m_spRegistration.IsNull()) + { + mapDefaultExceptionMacro(<< "Error. Cannot map point. Wrapper points to invalid registration (NULL). Point: " << inPoint); + } + + bool result = false; + + if ((this->GetMovingDimensions() == VMovingDim)&&(this->GetTargetDimensions() == VTargetDim)) + { + MAPTargetPointType tempInP; + MAPMovingPointType tempOutP; + tempInP.CastFrom(inPoint); + + typedef map::core::Registration CastedRegType; + const CastedRegType* pCastedReg = dynamic_cast(m_spRegistration.GetPointer()); + + if (!pCastedReg) + { + mapDefaultExceptionMacro(<< "Error. Cannot map point. Registration has invalid dimension. Point: " << inPoint); + } + + result = pCastedReg->mapPointInverse(tempInP,tempOutP); + if (result) + { + outPoint.CastFrom(tempOutP); + } + + } + + return result; +}; + + /*! returns the direct FieldRepresentationDescriptor which defines the part + of the moving space that is guaranteed to be mapped by the direct mapping kernel. + This member converts the internal MatchPoint type into a mitk::Geometry3D. + @pre valid registration instance must be set. + @return smart pointer to a FieldRepresentationDescriptor for the supported registration space in the moving domain. + May be null if the direct registration kernel is global and thus not limited. + If there is a limitation, the retun value is not NULL. + @retval NULL no field representation set/requested by the creating registration algorithm. + */ + mitk::Geometry3D GetDirectFieldRepresentation() const; + + /*! returns the inverse FieldRepresentationDescriptor which defines the part + of the target space that is guaranteed to be mapped by the inverse mapping kernel. + This member converts the internal MatchPoint type into a mitk::Geometry3D. + @pre valid registration instance must be set. + @return a const FieldRepresentationDescriptor for the supported registration space in the target domain. + May be null if the inverse registration kernel is global and thus not limited. + If there is a limitation, the retun value is not NULL. + @retval NULL no field representation set/requested by the creating registration algorithm. + */ + mitk::Geometry3D GetInverseFieldRepresentation() const; + + /*! forces kernel to precompute, even if it is a LazyFieldKernel + @pre valid registration instance must be set. + @todo der LazyFieldBasedRegistrationKernel muss dann die stong guarantee erfllen beim erzeugen des feldes ansonsten + ist die garantie dieser methode nicht erfllbar. noch berprfen + */ + void PrecomputeDirectMapping(); + + /*! forces kernel to precompute, even if it is a LazyFieldKernel + @pre valid registration instance must be set. + @todo der LazyFieldBasedRegistrationKernel muss dann die stong guarantee erfllen beim erzeugen des feldes ansonsten + ist die garantie dieser methode nicht erfllbar. noch berprfen + */ + void PrecomputeInverseMapping(); + + map::core::RegistrationBase* GetRegistration(); + const map::core::RegistrationBase* GetRegistration() const; + + void SetRegistration(map::core::RegistrationBase* pReg); + +protected: + virtual void PrintSelf (std::ostream &os, itk::Indent indent) const; + + MAPRegistrationWrapper(); + virtual ~MAPRegistrationWrapper(); + + map::core::RegistrationBase::Pointer m_spRegistration; + +private: + + MAPRegistrationWrapper& operator = (const MAPRegistrationWrapper&); + MAPRegistrationWrapper(const MAPRegistrationWrapper&); + +}; + +} + +#endif + diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp new file mode 100644 index 0000000000..37bf4fdd5a --- /dev/null +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.cpp @@ -0,0 +1,129 @@ +/*=================================================================== + +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 "mitkMAPRegistrationWrapperObjectFactory.h" + +#include +#include +#include + +#include "mitkRegistrationWrapperMapper2D.h" +#include "mitkRegistrationWrapperMapper3D.h" +#include "mitkMAPRegistrationWrapper.h" + +typedef std::multimap MultimapType; + +mitk::MAPRegistrationWrapperObjectFactory::MAPRegistrationWrapperObjectFactory() +: CoreObjectFactoryBase() +{ + static bool alreadyDone = false; + if (!alreadyDone) + { + MITK_INFO << "MAPRegistrationWrapperObjectFactory c'tor" << std::endl; + + alreadyDone = true; + } + +} + +mitk::MAPRegistrationWrapperObjectFactory::~MAPRegistrationWrapperObjectFactory() +{ +} + +mitk::Mapper::Pointer +mitk::MAPRegistrationWrapperObjectFactory:: +CreateMapper(mitk::DataNode* node, MapperSlotId slotId) +{ + mitk::Mapper::Pointer newMapper=NULL; + + if ( slotId == mitk::BaseRenderer::Standard2D ) + { + std::string classname("MAPRegistrationWrapper"); + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::MITKRegistrationWrapperMapper2D::New(); + newMapper->SetDataNode(node); + } + } + else if ( slotId == mitk::BaseRenderer::Standard3D ) + { + std::string classname("MAPRegistrationWrapper"); + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::MITKRegistrationWrapperMapper3D::New(); + newMapper->SetDataNode(node); + } + } + + return newMapper; +}; + +void mitk::MAPRegistrationWrapperObjectFactory::SetDefaultProperties(mitk::DataNode* node) +{ + if(node==NULL) + return; + + mitk::DataNode::Pointer nodePointer = node; + + if(node->GetData() ==NULL) + return; + + if( dynamic_cast(node->GetData())!=NULL ) + { + mitk::MITKRegistrationWrapperMapperBase::SetDefaultProperties(node); + } +} + +const char* mitk::MAPRegistrationWrapperObjectFactory::GetFileExtensions() +{ + std::string fileExtension; + this->CreateFileExtensions(m_FileExtensionsMap, fileExtension); + return fileExtension.c_str(); +}; + +mitk::CoreObjectFactoryBase::MultimapType mitk::MAPRegistrationWrapperObjectFactory::GetFileExtensionsMap() +{ + return m_FileExtensionsMap; +} + +const char* mitk::MAPRegistrationWrapperObjectFactory::GetSaveFileExtensions() +{ + std::string fileExtension; + this->CreateFileExtensions(m_SaveFileExtensionsMap, fileExtension); + return fileExtension.c_str(); +} + +mitk::CoreObjectFactoryBase::MultimapType mitk::MAPRegistrationWrapperObjectFactory::GetSaveFileExtensionsMap() +{ + return m_SaveFileExtensionsMap; +} + +struct RegisterMAPRegistrationWrapperObjectFactoryHelper{ + RegisterMAPRegistrationWrapperObjectFactoryHelper() + : m_Factory( mitk::MAPRegistrationWrapperObjectFactory::New() ) + { + mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory( m_Factory ); + } + + ~RegisterMAPRegistrationWrapperObjectFactoryHelper() + { + mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory( m_Factory ); + } + + mitk::MAPRegistrationWrapperObjectFactory::Pointer m_Factory; +}; + +static RegisterMAPRegistrationWrapperObjectFactoryHelper registerMITKRegistrationWrapperIOFactoryHelper; diff --git a/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h new file mode 100644 index 0000000000..8b425f62f7 --- /dev/null +++ b/Modules/MatchPointRegistration/mitkMAPRegistrationWrapperObjectFactory.h @@ -0,0 +1,71 @@ +/*=================================================================== + +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 __mitkMAPRegistrationWrapperObjectFactory_h +#define __mitkMAPRegistrationWrapperObjectFactory_h + +#include +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk { + +class MAPRegistrationWrapperObjectFactory : public mitk::CoreObjectFactoryBase +{ + public: + mitkClassMacro(MAPRegistrationWrapperObjectFactory,CoreObjectFactoryBase); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + ~MAPRegistrationWrapperObjectFactory(); + + virtual void SetDefaultProperties(mitk::DataNode* node); + + /** + * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil + */ + DEPRECATED(virtual const char* GetFileExtensions()); + /** + * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil + */ + DEPRECATED(virtual mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap()); + /** + * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil + */ + DEPRECATED(virtual const char* GetSaveFileExtensions()); + /** + * @deprecatedSince{2014_10} See mitk::FileWriterRegistry and QmitkIOUtil + */ + DEPRECATED(virtual mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap()); + + virtual mitk::Mapper::Pointer CreateMapper(mitk::DataNode* node, MapperSlotId slotId); + + protected: + MAPRegistrationWrapperObjectFactory(); + private: + void CreateFileExtensionsMap(); + std::string m_ExternalFileExtensions; + std::string m_InternalFileExtensions; + std::string m_SaveFileExtensions; + MultimapType m_FileExtensionsMap; + MultimapType m_SaveFileExtensionsMap; + + itk::ObjectFactoryBase::Pointer m_RegistrationWrapperIOFactory; +}; + +} + +#endif diff --git a/Modules/MatchPointRegistration/mitkMatchPointPropertyTags.h b/Modules/MatchPointRegistration/mitkMatchPointPropertyTags.h new file mode 100644 index 0000000000..39dae53e31 --- /dev/null +++ b/Modules/MatchPointRegistration/mitkMatchPointPropertyTags.h @@ -0,0 +1,40 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_MATCHPOINTPROPERTY_TAGS__H_ +#define _MITK_MATCHPOINTPROPERTY_TAGS__H_ + +// MITK +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ +const char* const nodeProp_RegAlgUsed = "matchpoint.Registration.Algorithm.UID"; +const char* const nodeProp_RegAlgTargetData = "matchpoint.Registration.Algorithm.UsedData.target"; +const char* const nodeProp_RegAlgMovingData = "matchpoint.Registration.Algorithm.UsedData.moving"; +const char* const nodeProp_RegUID = "matchpoint.Registration.UID"; +const char* const nodeProp_MappingInput = "matchpoint.Mapping.Input"; +const char* const nodeProp_MappingInputData = "matchpoint.Mapping.Input.Data"; +const char* const nodeProp_MappingInterpolator = "matchpoint.Mapping.Interpolator"; +const char* const nodeProp_MappingRefinedGeometry = "matchpoint.Mapping.RefinedGeometry"; +const char* const nodeProp_UID = "matchpoint.UID"; + +} + + +#endif + + diff --git a/Modules/MatchPointRegistration/mitkRegEvaluationObject.cpp b/Modules/MatchPointRegistration/mitkRegEvaluationObject.cpp new file mode 100644 index 0000000000..a504ef51c2 --- /dev/null +++ b/Modules/MatchPointRegistration/mitkRegEvaluationObject.cpp @@ -0,0 +1,133 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include +#include + +#include +#include + +#include "mitkRegEvaluationObject.h" + +#include + +namespace mitk +{ + + RegEvaluationObject::RegEvaluationObject() + { + } + + RegEvaluationObject::~RegEvaluationObject() + { + } + + void RegEvaluationObject::SetRequestedRegionToLargestPossibleRegion() + { + //nothing to do + } + + bool RegEvaluationObject::RequestedRegionIsOutsideOfTheBufferedRegion() + { + return false; + } + + bool RegEvaluationObject::VerifyRequestedRegion() + { + return true; + } + + void RegEvaluationObject::SetRequestedRegion(const itk::DataObject*) + { + //nothing to do + } + + void RegEvaluationObject::SetTargetImage(const mitk::Image* tImg) + { + itkDebugMacro("setting TargetImage to " << tImg); + + AccessFixedDimensionByItk_n(tImg, doConversion, 3, (m_TargetImage)); + + this->Modified(); + }; + + void RegEvaluationObject::SetMovingImage(const mitk::Image* mImg) + { + itkDebugMacro("setting MovingImage to " << mImg); + + AccessFixedDimensionByItk_n(mImg, doConversion, 3, (m_MovingImage)); + + this->Modified(); + }; + + template + void RegEvaluationObject::doConversion(const ::itk::Image* input, mitk::Image::Pointer& result) const + { + typedef ::itk::Image InputImageType; + typedef itk::CastImageFilter CastFilterType; + typedef itk::RescaleIntensityImageFilter RescaleFilterType; + + typename CastFilterType::Pointer caster = CastFilterType::New(); + typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); + + rescaler->SetInput(input); + rescaler->SetOutputMinimum(0); + rescaler->SetOutputMaximum(255); + caster->SetInput(rescaler->GetOutput()); + caster->Update(); + InternalImageType::Pointer internalImage = caster->GetOutput(); + + mitk::CastToMitkImage<>(internalImage,result); + } + + + void RegEvaluationObject::PrintSelf (std::ostream &os, itk::Indent indent) const + { + Superclass::PrintSelf(os,indent); + if (m_Registration.IsNull()) + { + os<< "Error. Eval object points to invalid registration (NULL)."; + } + else + { + os<Print(os,indent.GetNextIndent()); + } + + if (m_TargetImage.IsNull()) + { + os<< "Error. Eval object points to invalid target image (NULL)."; + } + else + { + os<Print(os,indent.GetNextIndent()); + } + + if (m_MovingImage.IsNull()) + { + os<< "Error. Eval object points to invalid moving image (NULL)."; + } + else + { + os<Print(os,indent.GetNextIndent()); + } + + } + +} + diff --git a/Modules/MatchPointRegistration/mitkRegEvaluationObject.h b/Modules/MatchPointRegistration/mitkRegEvaluationObject.h new file mode 100644 index 0000000000..9d70665dc4 --- /dev/null +++ b/Modules/MatchPointRegistration/mitkRegEvaluationObject.h @@ -0,0 +1,105 @@ +/*=================================================================== + +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 mitkRegEvaluationObject_h +#define mitkRegEvaluationObject_h + +//MITK +#include + +//MatchPoint +#include +#include +#include +#include + +//MITK +#include "mitkMAPRegistrationWrapper.h" +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk +{ + /*! + \brief RegEvaluationObject + Class that containes all data to realize an evaluation of registrations via images. + */ + class MITKMATCHPOINTREGISTRATION_EXPORT RegEvaluationObject: public mitk::BaseData + { + public: + + mitkClassMacro( RegEvaluationObject, BaseData ); + + itkNewMacro( Self ); + + /** + * Pass through to the target image that defines the region + */ + virtual void SetRequestedRegionToLargestPossibleRegion(); + + /** + * Pass through to the target image that defines the region + */ + virtual bool RequestedRegionIsOutsideOfTheBufferedRegion(); + + /** + * Pass through to the target image that defines the region + */ + virtual bool VerifyRequestedRegion(); + + /** + * Pass through to the target image that defines the region + */ + virtual void SetRequestedRegion(const itk::DataObject*); + + itkSetObjectMacro(Registration, mitk::MAPRegistrationWrapper); + + /**takes the input image, rescales it and converts it to pixel type int to be used for visualization as target image*/ + void SetTargetImage(const mitk::Image* tImg); + /**takes the input image, rescales it and converts it to pixel type int to be used for visualization as mapped moving*/ + void SetMovingImage(const mitk::Image* mImg); + + itkGetObjectMacro(Registration, mitk::MAPRegistrationWrapper); + itkGetObjectMacro(TargetImage, mitk::Image); + itkGetObjectMacro(MovingImage, mitk::Image); + + itkGetConstObjectMacro(Registration, mitk::MAPRegistrationWrapper); + itkGetConstObjectMacro(TargetImage, mitk::Image); + itkGetConstObjectMacro(MovingImage, mitk::Image); + + protected: + typedef ::itk::Image InternalImageType; + + template + void doConversion(const ::itk::Image* input, mitk::Image::Pointer& result) const; + + virtual void PrintSelf (std::ostream &os, itk::Indent indent) const; + + RegEvaluationObject(); + virtual ~RegEvaluationObject(); + + mitk::MAPRegistrationWrapper::Pointer m_Registration; + mitk::Image::Pointer m_TargetImage; + mitk::Image::Pointer m_MovingImage; + + private: + RegEvaluationObject& operator = (const RegEvaluationObject&); + RegEvaluationObject(const RegEvaluationObject&); + }; + +} + +#endif + diff --git a/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.cpp b/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.cpp new file mode 100644 index 0000000000..592cfae93c --- /dev/null +++ b/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.cpp @@ -0,0 +1,109 @@ +/*=================================================================== + +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 "mitkRegEvaluationObjectFactory.h" + +#include +#include +#include + +#include "mitkRegEvaluationMapper2D.h" + +typedef std::multimap MultimapType; + +mitk::RegEvaluationObjectFactory::RegEvaluationObjectFactory() +: CoreObjectFactoryBase() +{ + static bool alreadyDone = false; + if (!alreadyDone) + { + MITK_INFO << "RegEvaluationObjectFactory c'tor" << std::endl; + + alreadyDone = true; + } + +} + +mitk::RegEvaluationObjectFactory::~RegEvaluationObjectFactory() +{ +} + +mitk::Mapper::Pointer +mitk::RegEvaluationObjectFactory:: +CreateMapper(mitk::DataNode* node, MapperSlotId slotId) +{ + mitk::Mapper::Pointer newMapper = NULL; + + if ( slotId == mitk::BaseRenderer::Standard2D ) + { + std::string classname("RegEvaluationObject"); + if(node->GetData() && classname.compare(node->GetData()->GetNameOfClass())==0) + { + newMapper = mitk::RegEvaluationMapper2D::New(); + newMapper->SetDataNode(node); + } + } + + return newMapper; +}; + +void mitk::RegEvaluationObjectFactory::SetDefaultProperties(mitk::DataNode* node) +{ + +} + +const char* mitk::RegEvaluationObjectFactory::GetFileExtensions() +{ + //return empty (dummy) extension string + return m_FileExtensions.c_str(); +}; + +mitk::CoreObjectFactoryBase::MultimapType mitk::RegEvaluationObjectFactory::GetFileExtensionsMap() +{ + return mitk::CoreObjectFactoryBase::MultimapType(); +} + +const char* mitk::RegEvaluationObjectFactory::GetSaveFileExtensions() +{ + //return empty (dummy) extension string + return m_FileExtensions.c_str(); +} + +mitk::CoreObjectFactoryBase::MultimapType mitk::RegEvaluationObjectFactory::GetSaveFileExtensionsMap() +{ + return mitk::CoreObjectFactoryBase::MultimapType(); +} + +void mitk::RegEvaluationObjectFactory::RegisterIOFactories() +{ +} + +struct RegisterRegEvaluationObjectFactoryHelper{ + RegisterRegEvaluationObjectFactoryHelper() + : m_Factory( mitk::RegEvaluationObjectFactory::New() ) + { + mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory( m_Factory ); + } + + ~RegisterRegEvaluationObjectFactoryHelper() + { + mitk::CoreObjectFactory::GetInstance()->UnRegisterExtraFactory( m_Factory ); + } + + mitk::RegEvaluationObjectFactory::Pointer m_Factory; +}; + +static RegisterRegEvaluationObjectFactoryHelper registerMITKRegistrationWrapperIOFactoryHelper; diff --git a/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.h b/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.h new file mode 100644 index 0000000000..b3b1740d6c --- /dev/null +++ b/Modules/MatchPointRegistration/mitkRegEvaluationObjectFactory.h @@ -0,0 +1,49 @@ +/*=================================================================== + +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 __MITKRegEvaluationObjectFactory_h +#define __MITKRegEvaluationObjectFactory_h + +#include +#include "MitkMatchPointRegistrationExports.h" + +namespace mitk { + + /** Factory that registers everything (the mapper) needed for handling + RegEvaluationObject instances in MITK.*/ + class RegEvaluationObjectFactory : public mitk::CoreObjectFactoryBase + { + public: + mitkClassMacro(RegEvaluationObjectFactory,CoreObjectFactoryBase); + itkNewMacro(RegEvaluationObjectFactory); + + ~RegEvaluationObjectFactory(); + + virtual void SetDefaultProperties(mitk::DataNode* node); + virtual const char* GetFileExtensions(); + virtual mitk::CoreObjectFactoryBase::MultimapType GetFileExtensionsMap(); + virtual const char* GetSaveFileExtensions(); + virtual mitk::CoreObjectFactoryBase::MultimapType GetSaveFileExtensionsMap(); + virtual mitk::Mapper::Pointer CreateMapper(mitk::DataNode* node, MapperSlotId slotId); + void RegisterIOFactories(); + protected: + std::string m_FileExtensions; + RegEvaluationObjectFactory(); + }; + +} + +#endif diff --git a/Modules/MatchPointRegistrationUI/CMakeLists.txt b/Modules/MatchPointRegistrationUI/CMakeLists.txt new file mode 100644 index 0000000000..85cc6a2e28 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/CMakeLists.txt @@ -0,0 +1,5 @@ +MITK_CREATE_MODULE( + INCLUDE_DIRS Common Qmitk + DEPENDS MitkQtWidgets MitkQtWidgetsExt MitkMatchPointRegistration + PACKAGE_DEPENDS Qt5|Core CTK|CTKWidgets +) diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.cpp new file mode 100644 index 0000000000..c9b10fd36b --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.cpp @@ -0,0 +1,149 @@ +/*=================================================================== + +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 "QmitkAlgorithmListModel.h" + +#include "mapAlgorithmProfileHelper.h" + + + +QmitkAlgorithmListModel:: + QmitkAlgorithmListModel(QObject *parent) : +QAbstractTableModel(parent) +{ + +} + +void + QmitkAlgorithmListModel:: + SetAlgorithms(::map::deployment::DLLDirectoryBrowser::DLLInfoListType algList) +{ + emit beginResetModel(); + + m_AlgList = algList; + + emit endResetModel(); +}; + +int + QmitkAlgorithmListModel:: + rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + { + return 0; + } + + return m_AlgList.size(); +} + +int + QmitkAlgorithmListModel:: + columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return 4; +} + +QVariant + QmitkAlgorithmListModel:: + data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + QVariant result; + + if(index.row()getAlgorithmUID().getName().c_str()); + break; + case 1: + result = QVariant(info->getAlgorithmUID().getNamespace().c_str()); + break; + case 2: + result = QVariant(info->getAlgorithmUID().getVersion().c_str()); + break; + case 3: + std::stringstream descriptionString; + ::map::algorithm::profile::ValueListType keys = ::map::algorithm::profile::getKeywords(info->getAlgorithmProfileStr()); + for (::map::algorithm::profile::ValueListType::const_iterator keyPos = keys.begin(); keyPos!=keys.end();++keyPos) + { + if (keyPos != keys.begin()) + { + descriptionString << "; "; + } + descriptionString << *keyPos; + } + descriptionString << "

"; + result = QVariant(descriptionString.str().c_str()); + break; + } + } + else if (Qt::UserRole == role) + { + result = QVariant(index.row()); + } + + } + + return result; +} + +Qt::ItemFlags + QmitkAlgorithmListModel:: + flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + return flags; +} + +QVariant + QmitkAlgorithmListModel:: + headerData(int section, Qt::Orientation orientation, int role) const +{ + if( (Qt::DisplayRole == role) && + (Qt::Horizontal == orientation)) + { + if (section==0) + { + return QVariant("Name"); + } + else if (section==1) + { + return QVariant("Namespace"); + } + else if (section==2) + { + return QVariant("Version"); + } + else if (section==3) + { + return QVariant("Keywords"); + } + } + return QVariant(); +} diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.h new file mode 100644 index 0000000000..a284d4e65b --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmListModel.h @@ -0,0 +1,56 @@ +/*=================================================================== + +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 QmitkAlgorithmListModel_h +#define QmitkAlgorithmListModel_h + +#include +#include + +//MITK +#include "MitkMatchPointRegistrationUIExports.h" + +// MatchPoint +#include + +/*! + \class QmitkAlgorithmListModel + Model that takes a list of MatchPoint algorithm dll handles and represents it as model in context of the QT view-model-concept. + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkAlgorithmListModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + QmitkAlgorithmListModel(QObject *parent = NULL); + virtual ~QmitkAlgorithmListModel() {}; + + void SetAlgorithms(::map::deployment::DLLDirectoryBrowser::DLLInfoListType algList); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + +private: + + ::map::deployment::DLLDirectoryBrowser::DLLInfoListType m_AlgList; +}; + +#endif // mitkQmitkAlgorithmListModel_h + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.cpp new file mode 100644 index 0000000000..1836dfa4ce --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.cpp @@ -0,0 +1,166 @@ +/*=================================================================== + +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 "QmitkAlgorithmProfileViewer.h" + +#include +#include + +QmitkAlgorithmProfileViewer::QmitkAlgorithmProfileViewer(QWidget*) +{ + this->setupUi(this); +} + +void QmitkAlgorithmProfileViewer::OnInfoChanged(const map::deployment::DLLInfo* newInfo) +{ + updateInfo(newInfo); +} + +std::string AddInfoTableRow(const std::string& name, + const ::map::algorithm::profile::ValueListType& values, + const std::string& defaultStr ="") +{ + std::stringstream descriptionString; + descriptionString << ""<"; + + if (!values.empty()) + { + for (::map::algorithm::profile::ValueListType::const_iterator pos = values.begin(); pos!=values.end();++pos) + { + if (pos != values.begin()) + { + descriptionString << "
"; + } + descriptionString << *pos; + } + } + else + { + if (defaultStr.empty()) + { + descriptionString << "unknown / not defined"; + } + else + { + descriptionString << defaultStr; + } + } + + descriptionString << ""; + + return descriptionString.str(); +} + +void QmitkAlgorithmProfileViewer::updateInfo(const map::deployment::DLLInfo* newInfo) +{ + if( !newInfo ) + { + this->m_teAlgorithmDetails->clear(); + } + else + { + std::stringstream descriptionString; + + ::map::structuredData::Element::Pointer algProfile = ::map::algorithm::profile::parseProfileString(newInfo->getAlgorithmProfileStr()); + // create description string + descriptionString << "

Identification

Namespace: "<< newInfo->getAlgorithmUID().getNamespace() << "
" + << "Name: "<< newInfo->getAlgorithmUID().getName() << "
" + << "Version: "<< newInfo->getAlgorithmUID().getVersion() << "
" + << "BuildTag: "<< newInfo->getAlgorithmUID().getBuildTag() << "
" + << "Location: "<< newInfo->getLibraryFilePath() << "

"; + + descriptionString << "

Description

"<< ::map::algorithm::profile::getDescription(algProfile)<< "

"; + descriptionString << "

Keywords

"; + ::map::algorithm::profile::ValueListType keys = ::map::algorithm::profile::getKeywords(algProfile); + for (::map::algorithm::profile::ValueListType::const_iterator keyPos = keys.begin(); keyPos!=keys.end();++keyPos) + { + if (keyPos != keys.begin()) + { + descriptionString << "; "; + } + descriptionString << *keyPos; + } + descriptionString << "

"; + + descriptionString << "

Characteristics

"; + descriptionString << AddInfoTableRow("data type(s)", ::map::algorithm::profile::getDataType(algProfile)); + descriptionString << AddInfoTableRow("computation style", ::map::algorithm::profile::getComputationStyle(algProfile)); + if (::map::algorithm::profile::isDeterministic(algProfile)) + { + descriptionString << ""; + } + else + { + descriptionString << ""; + } + descriptionString << AddInfoTableRow("resolution style", ::map::algorithm::profile::getResolutionStyle(algProfile)); + + unsigned int dimension; + + descriptionString << ""; + descriptionString << AddInfoTableRow("moving modality", ::map::algorithm::profile::getMovingModality(algProfile)); + + descriptionString << ""; + descriptionString << AddInfoTableRow("target modality", ::map::algorithm::profile::getTargetModality(algProfile)); + + descriptionString << AddInfoTableRow("subject", ::map::algorithm::profile::getSubject(algProfile)); + descriptionString << AddInfoTableRow("object", ::map::algorithm::profile::getObject(algProfile)); + descriptionString << AddInfoTableRow("transform model", ::map::algorithm::profile::getTransformModel(algProfile)); + descriptionString << AddInfoTableRow("transform domain", ::map::algorithm::profile::getTransformDomain(algProfile)); + descriptionString << AddInfoTableRow("metric", ::map::algorithm::profile::getMetric(algProfile)); + descriptionString << AddInfoTableRow("optimization", ::map::algorithm::profile::getOptimization(algProfile)); + descriptionString << AddInfoTableRow("interaction", ::map::algorithm::profile::getInteraction(algProfile)); + descriptionString << "
deterministic:yes
deterministic:no
moving dim:"; + if (::map::algorithm::profile::getMovingDimensions(algProfile,dimension)) + { + descriptionString << map::core::convert::toStr(dimension)<<"D"; + } + else + { + descriptionString << "unknown / not defined"; + } + descriptionString<<"
target dim:"; + if (::map::algorithm::profile::getTargetDimensions(algProfile,dimension)) + { + descriptionString << map::core::convert::toStr(dimension)<<"D"; + } + else + { + descriptionString << "unknown / not defined"; + } + descriptionString<<"
"; + + descriptionString << "

Contact & Usage

"; + descriptionString << AddInfoTableRow("contact", ::map::algorithm::profile::getContact(algProfile)); + std::string terms; + descriptionString << ""; + descriptionString << AddInfoTableRow("citation", ::map::algorithm::profile::getCitation(algProfile)); + descriptionString <<"
terms:"; + if (::map::algorithm::profile::getTerms(algProfile,terms)) + { + descriptionString<unknown / not defined"; + } + descriptionString <<"
"; + + // update the info label + this->m_teAlgorithmDetails->clear(); + this->m_teAlgorithmDetails->insertHtml( QString::fromStdString( descriptionString.str() ) ); + } +} diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.h new file mode 100644 index 0000000000..13a2c62321 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.h @@ -0,0 +1,54 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef QMITK_ALGORITHM_PROFILE_VIEWER_H +#define QMITK_ALGORITHM_PROFILE_VIEWER_H + +#include + +#include + +#include "ui_QmitkAlgorithmProfileViewer.h" +#include + +/** + * \class QmitkAlgorithmProfileViewer + * \brief Widget that views the information and profile of an algorithm stored in an DLLInfo object. + */ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkAlgorithmProfileViewer : public QWidget, private Ui::QmitkAlgorithmProfileViewer +{ + Q_OBJECT + +public: + QmitkAlgorithmProfileViewer(QWidget* parent=0); + + /** + * \brief Updates the widget according to the new info. + * \param pointer to the info instance. + * \remark The DLLInfo is not stored internally or as reference + * to update the widget you must use the updateInfo() method. + */ + void updateInfo(const map::deployment::DLLInfo* newInfo); + +public Q_SLOTS: + /** + * \brief Slot that can be used to trigger updateInfo(); + */ + void OnInfoChanged(const map::deployment::DLLInfo* newInfo); +}; + +#endif // QmitkAlgorithmProfileViewer_H diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.ui b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.ui new file mode 100644 index 0000000000..57e9321dc9 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmProfileViewer.ui @@ -0,0 +1,61 @@ + + + QmitkAlgorithmProfileViewer + + + + 0 + 0 + 554 + 898 + + + + Form + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QFrame::StyledPanel + + + false + + + QTextEdit::WidgetWidth + + + 0 + + + true + + + Qt::NoTextInteraction + + + + + + + + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.cpp new file mode 100644 index 0000000000..87437588a1 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.cpp @@ -0,0 +1,60 @@ +/*=================================================================== + +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 "QmitkAlgorithmSettingsConfig.h" + +#include +#include + +QmitkAlgorithmSettingsConfig::QmitkAlgorithmSettingsConfig(QWidget*) +{ + this->setupUi(this); + + m_AlgorithmModel = new QmitkMAPAlgorithmModel(this); + m_ProxyModel = new QSortFilterProxyModel(this); + + // configure property model/view/widget + m_ProxyModel->setSourceModel(m_AlgorithmModel); + m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_ProxyModel->setDynamicSortFilter(true); + + this->m_AlgoPropertiesView->setModel(m_ProxyModel); + this->m_AlgoPropertiesView->setSortingEnabled(true); + this->m_AlgoPropertiesView->setAlternatingRowColors(true); + this->m_AlgoPropertiesView->setSelectionMode(QAbstractItemView::SingleSelection); + this->m_AlgoPropertiesView->setSelectionBehavior(QAbstractItemView::SelectItems); +} + +void setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg); + +map::algorithm::RegistrationAlgorithmBase* getAlgorithm(); + +void QmitkAlgorithmSettingsConfig::setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg) +{ + if (alg != this->m_currentAlg) + { + this->m_currentAlg = alg; + this->m_AlgorithmModel->SetAlgorithm(this->m_currentAlg); + + this->m_AlgoPropertiesView->setWindowModified(true); + this->m_AlgoPropertiesView->update(); + } +} + +map::algorithm::RegistrationAlgorithmBase* QmitkAlgorithmSettingsConfig::getAlgorithm() +{ + return this->m_currentAlg; +} \ No newline at end of file diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.h new file mode 100644 index 0000000000..1d38f43423 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.h @@ -0,0 +1,59 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITK_ALGORITHM_SETTINGS_CONFIG_H +#define QMITK_ALGORITHM_SETTINGS_CONFIG_H + +#include +#include + +#include + +#include + +#include + +#include "ui_QmitkAlgorithmSettingsConfig.h" + +/** + * \class QmitkAlgorithmSettingsConfig + * \brief Widget that views the information and profile of an algorithm stored in an DLLInfo object. + */ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkAlgorithmSettingsConfig : public QWidget, private Ui::QmitkAlgorithmSettingsConfig +{ + Q_OBJECT + +public: + QmitkAlgorithmSettingsConfig(QWidget* parent=0); + + /** + * \brief Changes the current algorithm and updates widget accordingly. + * \param pointer to the algorithm instance. + */ + void setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg); + + map::algorithm::RegistrationAlgorithmBase* getAlgorithm(); + +protected: + /** Pointer to the algorithm that should be configured */ + map::algorithm::RegistrationAlgorithmBase::Pointer m_currentAlg; + + // control the properties of the selected algorithm + QmitkMAPAlgorithmModel* m_AlgorithmModel; + QSortFilterProxyModel* m_ProxyModel; +}; + +#endif // QmitkAlgorithmSettingsConfig_H diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.ui b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.ui new file mode 100644 index 0000000000..ffc420825d --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkAlgorithmSettingsConfig.ui @@ -0,0 +1,80 @@ + + + QmitkAlgorithmSettingsConfig + + + + 0 + 0 + 271 + 534 + + + + Form + + + + 0 + + + 0 + + + + + 0 + + + + Properties + + + + 0 + + + + + + 0 + 0 + + + + + 250 + 0 + + + + true + + + true + + + true + + + + + + + + false + + + Configuration of the multi resolution scheme of an algorithm. + + + Multi resolution + + + + + + + + + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.cpp new file mode 100644 index 0000000000..39765da175 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.cpp @@ -0,0 +1,230 @@ +/*=================================================================== + +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 "QmitkFramesRegistrationJob.h" + +// Mitk +#include + +// Qt +#include + +// Map4CTK +#include +#include +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include + + +const mitk::Image* +QmitkFramesRegistrationJob:: +GetTargetDataAsImage() const +{ + return dynamic_cast(m_spTargetData.GetPointer()); +}; + +const map::algorithm::RegistrationAlgorithmBase* QmitkFramesRegistrationJob::GetLoadedAlgorithm() +const +{ + return m_spLoadedAlgorithm; +}; + +void QmitkFramesRegistrationJob::OnMapAlgorithmEvent(::itk::Object*, const itk::EventObject& event) +{ + const map::events::AlgorithmEvent* pAlgEvent = dynamic_cast < const map::events::AlgorithmEvent* > + (&event); + const map::events::AlgorithmIterationEvent* pIterationEvent = + dynamic_cast(&event); + const map::events::AlgorithmWrapperEvent* pWrapEvent = + dynamic_cast(&event); + const map::events::AlgorithmResolutionLevelEvent* pLevelEvent = + dynamic_cast(&event); + + const map::events::InitializingAlgorithmEvent* pInitEvent = + dynamic_cast(&event); + const map::events::StartingAlgorithmEvent* pStartEvent = + dynamic_cast(&event); + const map::events::StoppingAlgorithmEvent* pStoppingEvent = + dynamic_cast(&event); + const map::events::StoppedAlgorithmEvent* pStoppedEvent = + dynamic_cast(&event); + const map::events::FinalizingAlgorithmEvent* pFinalizingEvent = + dynamic_cast(&event); + const map::events::FinalizedAlgorithmEvent* pFinalizedEvent = + dynamic_cast(&event); + const itk::ProgressEvent* pProgressEvent = + dynamic_cast(&event); + const mitk::FrameRegistrationEvent* pFrameRegEvent = + dynamic_cast(&event); + const mitk::FrameMappingEvent* pFrameMapEvent = + dynamic_cast(&event); + + if (pProgressEvent) + { + emit FrameProcessed(m_helper->GetProgress()); + } + else if (pFrameRegEvent) + { + emit FrameRegistered(m_helper->GetProgress()); + } + else if (pFrameMapEvent) + { + emit FrameMapped(m_helper->GetProgress()); + } + else if (pInitEvent) + { + emit AlgorithmStatusChanged(QString("Initializing algorithm ...")); + } + else if (pStartEvent) + { + emit AlgorithmStatusChanged(QString("Starting algorithm ...")); + } + else if (pStoppingEvent) + { + emit AlgorithmStatusChanged(QString("Stopping algorithm ...")); + } + else if (pStoppedEvent) + { + emit AlgorithmStatusChanged(QString("Stopped algorithm ...")); + + if (!pStoppedEvent->getComment().empty()) + { + emit AlgorithmInfo(QString("Stopping condition: ") + QString::fromStdString( + pStoppedEvent->getComment())); + } + } + else if (pFinalizingEvent) + { + emit AlgorithmStatusChanged(QString("Finalizing algorithm and results ...")); + } + else if (pFinalizedEvent) + { + emit AlgorithmStatusChanged(QString("Finalized algorithm ...")); + } + else if (pIterationEvent) + { + const IIterativeAlgorithm* pIterative = dynamic_cast + (this->m_spLoadedAlgorithm.GetPointer()); + + map::algorithm::facet::IterativeAlgorithmInterface::IterationCountType count = 0; + bool hasCount = false; + + if (pIterative && pIterative->hasIterationCount()) + { + hasCount = true; + count = pIterative->getCurrentIteration(); + } + + emit AlgorithmIterated(QString::fromStdString(pIterationEvent->getComment()), hasCount, count); + } + else if (pLevelEvent) + { + const IMultiResAlgorithm* pResAlg = dynamic_cast + (this->m_spLoadedAlgorithm.GetPointer()); + + map::algorithm::facet::MultiResRegistrationAlgorithmInterface::ResolutionLevelCountType count = 0; + bool hasCount = false; + QString info = QString::fromStdString(pLevelEvent->getComment()); + + if (pResAlg && pResAlg->hasLevelCount()) + { + count = pResAlg->getCurrentLevel() + 1; + hasCount = true; + info = QString("Level #") + QString::number(pResAlg->getCurrentLevel() + 1) + QString(" ") + info; + } + + emit LevelChanged(info, hasCount, count); + } + else if (pAlgEvent && !pWrapEvent) + { + emit AlgorithmInfo(QString::fromStdString(pAlgEvent->getComment())); + } +} + +QmitkFramesRegistrationJob:: +QmitkFramesRegistrationJob(map::algorithm::RegistrationAlgorithmBase* pAlgorithm) : + m_spLoadedAlgorithm(pAlgorithm), + m_TargetNodeUID("Missing target UID") +{ + m_MappedName = "Unnamed RegJob"; + + m_spTargetMask = NULL; + + m_spCommand = ::itk::MemberCommand::New(); + m_spCommand->SetCallbackFunction(this, &QmitkFramesRegistrationJob::OnMapAlgorithmEvent); + m_ObserverID = m_spLoadedAlgorithm->AddObserver(::map::events::AlgorithmEvent(), m_spCommand); +}; + +QmitkFramesRegistrationJob:: +~QmitkFramesRegistrationJob() +{ + m_spLoadedAlgorithm->RemoveObserver(m_ObserverID); +}; + +void +QmitkFramesRegistrationJob:: +run() +{ + try + { + m_helper = mitk::TimeFramesRegistrationHelper::New(); + + m_helper->Set4DImage(this->GetTargetDataAsImage()); + m_helper->SetTargetMask(this->m_spTargetMask); + m_helper->SetAlgorithm(this->m_spLoadedAlgorithm); + m_helper->SetIgnoreList(this->m_IgnoreList); + + m_helper->SetAllowUndefPixels(this->m_allowUndefPixels); + m_helper->SetAllowUnregPixels(this->m_allowUnregPixels); + m_helper->SetErrorValue(this->m_errorValue); + m_helper->SetPaddingValue(this->m_paddingValue); + m_helper->SetInterpolatorType(this->m_InterpolatorType); + + m_helper->AddObserver(::map::events::AnyMatchPointEvent(), m_spCommand); + m_helper->AddObserver(::itk::ProgressEvent(), m_spCommand); + + //perform registration + m_spMappedImageNode = m_helper->GetRegisteredImage(); + + //wrap the registration in a data node + if (m_spMappedImageNode.IsNull()) + { + emit Error(QString("Error. No registration was determined. No results to store.")); + } + else + { + emit ResultIsAvailable(m_spMappedImageNode, this); + } + } + catch (::std::exception& e) + { + emit Error(QString("Error while registering data. Details: ") + QString::fromLatin1(e.what())); + } + catch (...) + { + emit Error(QString("Unkown error when registering data.")); + } + + emit Finished(); +}; diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.h new file mode 100644 index 0000000000..52c499085e --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkFramesRegistrationJob.h @@ -0,0 +1,106 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef __QMITK_FRAMES_REGISTRATION_JOB_H +#define __QMITK_FRAMES_REGISTRATION_JOB_H + + +//QT +#include +#include + +// ITK +#include + +//MITK +#include +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include + +//Map4CTK +#include "mitkUIDHelper.h" +#include + +#include + +/** Simple helper job class that could be used to process a frame registration in a paralell thread. + * This is e.g. used be plugins to keep the GUI responsive while doing a frame registration*/ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkFramesRegistrationJob : public QObject, public QRunnable, + public QmitkMappingJobSettings +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + QmitkFramesRegistrationJob(map::algorithm::RegistrationAlgorithmBase* pAlgorithm); + ~QmitkFramesRegistrationJob(); + + void run(); + +signals: + void Finished(); + void Error(QString err); + void ResultIsAvailable(mitk::Image::Pointer spResult, const QmitkFramesRegistrationJob* pJob); + void AlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration); + void LevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel); + void AlgorithmStatusChanged(QString info); + void AlgorithmInfo(QString info); + void FrameProcessed(double progress); + void FrameRegistered(double progress); + void FrameMapped(double progress); + +public: + //Inputs + mitk::BaseData::ConstPointer m_spTargetData; + + mitk::Image::ConstPointer m_spTargetMask; + + //job settings + mitk::TimeFramesRegistrationHelper::IgnoreListType m_IgnoreList; + mitk::NodeUIDType m_TargetNodeUID; + mitk::NodeUIDType m_TargetMaskNodeUID; + + const map::algorithm::RegistrationAlgorithmBase* GetLoadedAlgorithm() const; + +private: + typedef map::algorithm::facet::IterativeAlgorithmInterface IIterativeAlgorithm; + typedef map::algorithm::facet::MultiResRegistrationAlgorithmInterface IMultiResAlgorithm; + + mitk::Image::Pointer m_spMappedImageNode; + + ::itk::MemberCommand::Pointer m_spCommand; + unsigned long m_ObserverID; + map::algorithm::RegistrationAlgorithmBase::Pointer m_spLoadedAlgorithm; + + mitk::TimeFramesRegistrationHelper::Pointer m_helper; + + //Helper functions + const mitk::Image* GetTargetDataAsImage() const; + + void OnMapAlgorithmEvent(::itk::Object*, const itk::EventObject& event); +}; + +#endif + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.cpp new file mode 100644 index 0000000000..e5be4bb68b --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.cpp @@ -0,0 +1,335 @@ +/*=================================================================== + +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 "QmitkMAPAlgorithmModel.h" + +#include "mapMetaProperty.h" + +QmitkMAPAlgorithmModel:: +QmitkMAPAlgorithmModel(QObject *parent) : + QAbstractTableModel(parent), + m_pMetaInterface(NULL) +{ + +} + +void +QmitkMAPAlgorithmModel:: +SetAlgorithm(map::algorithm::RegistrationAlgorithmBase *pAlgorithm) +{ + this->SetAlgorithm(dynamic_cast(pAlgorithm)); +}; + +void +QmitkMAPAlgorithmModel:: +SetAlgorithm(map::algorithm::facet::MetaPropertyAlgorithmInterface *pMetaInterface) +{ + emit beginResetModel(); + + m_pMetaInterface = pMetaInterface; + this->UpdateMetaProperties(); + + emit endResetModel(); +}; + +int +QmitkMAPAlgorithmModel:: +rowCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + { + return 0; + } + + return m_MetaProperties.size(); +} + +int +QmitkMAPAlgorithmModel:: +columnCount(const QModelIndex &parent) const +{ + if(parent.isValid()) + return 0; + + return 2; +} + +QVariant +QmitkMAPAlgorithmModel:: +data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(!m_pMetaInterface) + { + return QVariant(); + } + + QVariant result; + + if(index.row()getName().c_str()); + } + break; + case 1: + if (Qt::DisplayRole == role && !pInfo->isReadable()) + { + result = QVariant("value is not accessible"); + } + else if (pInfo->isReadable() && (Qt::DisplayRole == role || (Qt::EditRole == role && pInfo->isWritable()))) + { //should also be readable to be sensible editable in the GUI + result = GetPropertyValue(pInfo,role); + } + break; + } + } + + return result; +} + +Qt::ItemFlags +QmitkMAPAlgorithmModel:: +flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if(index.row()isWritable()) + { + flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + } + } + } + + return flags; +} + +QVariant +QmitkMAPAlgorithmModel:: +headerData(int section, Qt::Orientation orientation, int role) const +{ + if( (Qt::DisplayRole == role) && + (Qt::Horizontal == orientation)) + { + if (section==0) + { + return QVariant("Property"); + } + else if (section==1) + { + return QVariant("Value"); + } + } + return QVariant(); +} + +bool +QmitkMAPAlgorithmModel:: +setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid() || (m_MetaProperties.size() <= index.row()) || (1 != index.column())) + { + return false; + } + + if(Qt::EditRole == role) + { + map::algorithm::MetaPropertyInfo* pInfo = m_MetaProperties[index.row()]; + + bool result = SetPropertyValue(pInfo,value); + + if (result) + { + emit beginResetModel(); + this->UpdateMetaProperties(); + emit endResetModel(); + } + + return result; + } + + return false; +}; + + +void +QmitkMAPAlgorithmModel:: +UpdateMetaProperties() const +{ + if(m_pMetaInterface) + { + m_MetaProperties = m_pMetaInterface->getPropertyInfos(); + } + else + { + m_MetaProperties.clear(); + } +} + +QVariant +QmitkMAPAlgorithmModel:: +GetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, int role) const +{ + if(!m_pMetaInterface) + { + return QVariant(); + } + + map::algorithm::facet::MetaPropertyAlgorithmInterface::MetaPropertyPointer prop = m_pMetaInterface->getProperty(pInfo); + + if(!prop) + { + return QVariant(); + } + + QVariant result; + + if (role == Qt::DisplayRole) + { + result = QVariant(QString("Error. Cannot unwrap MetaProperty. Name: ")+QString::fromStdString(pInfo->getName())); + } + + if (prop->getMetaPropertyTypeInfo()==typeid(bool)) + { + bool val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(int)) + { + int val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(unsigned int)) + { + unsigned int val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(long)) + { + long val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(qlonglong(val)); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(unsigned long)) + { + unsigned long val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(qulonglong(val)); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(float)) + { + float val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(double)) + { + double val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(val); + } + } + else if (prop->getMetaPropertyTypeInfo()==typeid(map::core::String)) + { + map::core::String val; + if (map::core::unwrapCastedMetaProperty(prop,val)) + { + result = QVariant(QString::fromStdString(val)); + } + } + else + { + if (role == Qt::DisplayRole) + { + result = QVariant(QString("Error. Cannot offer MetaProperty because of unsupported type. Property name: ")+QString::fromStdString(pInfo->getName())+QString("; type name: ")+QString(prop->getMetaPropertyTypeName())); + } + } + return result; +}; + +template +bool +QmitkMAPAlgorithmModel:: +CheckCastAndSetProp(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value) +{ + bool result = false; + if (pInfo->getTypeInfo()==typeid(TValueType) && value.canConvert()) + { + /**@TODO: Not save, because canConvert may say true but the actual value is not really convertible (e.g. string to int for the value "a")*/ + TValueType val = value.value(); + map::core::MetaPropertyBase::Pointer spMetaProp = map::core::MetaProperty::New(val).GetPointer(); + + result = m_pMetaInterface->setProperty(pInfo,spMetaProp); + } + return result; +}; + +bool +QmitkMAPAlgorithmModel:: +SetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value) +{ + if(!m_pMetaInterface) + { + return false; + } + + bool result = CheckCastAndSetProp(pInfo,value); + + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result) result = CheckCastAndSetProp(pInfo,value); + if (!result && pInfo->getTypeInfo()==typeid(map::core::String)) + { + map::core::String val = value.toString().toStdString(); + map::core::MetaPropertyBase::Pointer spMetaProp = map::core::MetaProperty::New(val).GetPointer(); + + result = m_pMetaInterface->setProperty(pInfo,spMetaProp); + }; + + return result; +}; diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.h new file mode 100644 index 0000000000..67d09bafc2 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMAPAlgorithmModel.h @@ -0,0 +1,76 @@ +/*=================================================================== + +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 QmitkMAPAlgorithmModel_h +#define QmitkMAPAlgorithmModel_h + +#include +#include + +//MITK +#include "MitkMatchPointRegistrationUIExports.h" + +// MatchPoint +#include +#include + +/*! + \class QmitkMAPAlgorithmModel + Helper class that implements a model to handle the MetaProperty interface of a MatchPoint algorithm + in contect of the QT view-model-concept. A algorithm can be set as data source for the model. + The model retrieves all information through the MetaPropertyInterface. Changes in the view will + be propagated by the model into the algorithm. + \remarks The model only keep a simple pointer to the MetaPropertyInterface of the algorithm. + You have to ensure to reset the algorithm if the pointer goes invalid. + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. +*/ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkMAPAlgorithmModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + QmitkMAPAlgorithmModel(QObject *parent = NULL); + virtual ~QmitkMAPAlgorithmModel() {}; + + void SetAlgorithm(map::algorithm::RegistrationAlgorithmBase *pAlgorithm); + void SetAlgorithm(map::algorithm::facet::MetaPropertyAlgorithmInterface *pMetaInterface); + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual QVariant data(const QModelIndex &index, int role) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + +private: + void UpdateMetaProperties() const ; + + /** Method uses m_pMetaInterface to retrieve the MetaProperty and unwraps it into an + * suitable QVariant depending on the passed QT role. If the MetaProperty type is not supported, the QVariant is invalid. + */ + QVariant GetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, int role) const; + + template bool CheckCastAndSetProp(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value); + + bool SetPropertyValue(const map::algorithm::MetaPropertyInfo* pInfo, const QVariant& value); + + map::algorithm::facet::MetaPropertyAlgorithmInterface *m_pMetaInterface; + mutable map::algorithm::facet::MetaPropertyAlgorithmInterface::MetaPropertyVectorType m_MetaProperties; +}; + +#endif + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.cpp new file mode 100644 index 0000000000..b18255751d --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.cpp @@ -0,0 +1,286 @@ +/*=================================================================== + +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 NOMINMAX +#define NOMINMAX +#endif + +#include "QmitkMapPropertyDelegate.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QmitkMapPropertyDelegate::QmitkMapPropertyDelegate(QObject * /*parent*/) +{ +} + +void QmitkMapPropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + + QVariant data = index.data(Qt::DisplayRole); + + QString name = data.value(); + + QStyledItemDelegate::paint(painter, option, index); + +} + +QWidget* QmitkMapPropertyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + QString name = index.model()->data(index.model()->index(index.row(), index.column()-1)).value(); + + if(data.isValid()) + { + + QWidget* editorWidget = NULL; + + if(data.type() == QVariant::Int) + { + QSpinBox* spinBox = new QSpinBox(parent); + spinBox->setSingleStep(1); + spinBox->setMinimum(std::numeric_limits::min()); + spinBox->setMaximum(std::numeric_limits::max()); + editorWidget = spinBox; + } + // see qt documentation. cast is correct, it would be obsolete if we + // store doubles + else if(static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); + spinBox->setDecimals(5); + spinBox->setSingleStep(0.1); + spinBox->setMinimum(std::numeric_limits::min()); + spinBox->setMaximum(std::numeric_limits::max()); + + editorWidget = spinBox; + } + else if(data.type() == QVariant::StringList) + { + QStringList entries = data.value(); + QComboBox* comboBox = new QComboBox(parent); + comboBox->setEditable(false); + comboBox->addItems(entries); + + editorWidget = comboBox; + } + else + { + editorWidget = QStyledItemDelegate::createEditor(parent, option, index); + } + + if ( editorWidget ) + { + // install event filter + editorWidget->installEventFilter( const_cast(this) ); + } + + return editorWidget; + + } + else + return new QLabel(displayData.toString(), parent); + +} + +void QmitkMapPropertyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + + std::cout << "Set EDITOR DATA : " << data.toDouble() << std::endl; + + if(data.isValid()) + { + + + if(data.type() == QVariant::Int) + { + QSpinBox* spinBox = qobject_cast(editor); + spinBox->setValue(data.toInt()); + } + // see qt documentation. cast is correct, it would be obsolete if we + // store doubles + else if(static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = qobject_cast(editor); + spinBox->setValue(data.toDouble()); + + std::cout << "Set EDITOR DATA : " << spinBox->value() << std::endl; + } + + else if(data.type() == QVariant::StringList) + { + QComboBox* comboBox = qobject_cast(editor); + QString displayString = displayData.value(); + comboBox->setCurrentIndex(comboBox->findData(displayString)); + } + + else + return QStyledItemDelegate::setEditorData(editor, index); + } +} + +void QmitkMapPropertyDelegate::setModelData(QWidget *editor, QAbstractItemModel* model + , const QModelIndex &index) const +{ + QVariant data = index.data(Qt::EditRole); + QVariant displayData = index.data(Qt::DisplayRole); + + if(data.isValid()) + { + + if(data.type() == QVariant::Color) + { + QWidget *colorBtn = qobject_cast(editor); + QVariant colorVariant; + colorVariant.setValue(colorBtn->palette().color(QPalette::Button)); + model->setData(index, colorVariant); + } + + else if(data.type() == QVariant::Int) + { + QSpinBox* spinBox = qobject_cast(editor); + int intValue = spinBox->value(); + + QVariant intValueVariant; + intValueVariant.setValue(static_cast(intValue)); + model->setData(index, intValueVariant); + } + + else if(static_cast(data.type()) == QMetaType::Float) + { + QDoubleSpinBox* spinBox = qobject_cast(editor); + double doubleValue = spinBox->value(); + + std::cout << "SET MODEL DATA << FLOAT : " << doubleValue <(static_cast(doubleValue)); + std::cout << "SET MODEL DATA << Variant : " << doubleValue <setData(index, doubleValueVariant); + } + + else if(data.type() == QVariant::StringList) + { + QString displayData = data.value(); + + QComboBox* comboBox = qobject_cast(editor); + QString comboBoxValue = comboBox->currentText(); + + QVariant comboBoxValueVariant; + comboBoxValueVariant.setValue(comboBoxValue); + model->setData(index, comboBoxValueVariant); + } + + else + QStyledItemDelegate::setModelData(editor, model, index); + } + +} + +void QmitkMapPropertyDelegate::commitAndCloseEditor() +{ + QWidget* editor = 0; + if(QPushButton *pushBtn = qobject_cast(sender())) + { + editor = pushBtn; + } + + if(editor) + { + emit commitData(editor); + emit closeEditor(editor); + } + +} + +void QmitkMapPropertyDelegate::updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex & /*index*/) const +{ + editor->setGeometry(option.rect); +} + +void QmitkMapPropertyDelegate::ComboBoxCurrentIndexChanged( int /*index*/ ) +{ + if(QComboBox *comboBox = qobject_cast(sender())) + { + emit commitData(comboBox); + emit closeEditor(comboBox); + } +} + +void QmitkMapPropertyDelegate::SpinBoxValueChanged( const QString& /*value*/ ) +{ + QAbstractSpinBox *spinBox = 0; + if((spinBox = qobject_cast(sender())) + || (spinBox = qobject_cast(sender()))) + { + emit commitData(spinBox); + emit closeEditor(spinBox); + } +} + +void QmitkMapPropertyDelegate::showColorDialog() +{ + +} + +bool QmitkMapPropertyDelegate::eventFilter( QObject *o, QEvent *e ) +{ + // filter all kind of events on our editor widgets + // when certain events occur, repaint all render windows, because rendering relevant properties might have changed + switch ( e->type() ) + { + case QEvent::KeyRelease: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::Wheel: + case QEvent::FocusIn: + { + if( QWidget* editor = dynamic_cast(o) ) + { + emit commitData(editor); + } + break; + } + default: + { + break; + } + } + + return false; +} diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.h new file mode 100644 index 0000000000..5bf1b85d05 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapPropertyDelegate.h @@ -0,0 +1,89 @@ +/*=================================================================== + +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 QmitkPropertyDelegate_h +#define QmitkPropertyDelegate_h + + +/// Toolkit includes. +#include +#include "mitkBaseProperty.h" + +//MITK +#include "MitkMatchPointRegistrationUIExports.h" + + +/// Forward declarations. + +/// +/// \class QmitkPropertyDelegate +/// \brief An item delegate for rendering and editing mitk::Properties in a QTableView. +/// +/// \see QmitkPropertiesTableModel +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkMapPropertyDelegate : public QStyledItemDelegate +{ + Q_OBJECT + + public: + /// + /// Creates a new PropertyDelegate. + /// + QmitkMapPropertyDelegate(QObject *parent = 0); + + /// + /// Renders a specific property (overwritten from QItemDelegate) + /// + void paint(QPainter *painter, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option + , const QModelIndex &index) const; + + /// + /// Create an editor for a specific property (overwritten from QItemDelegate) + /// + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + /// + /// When the user accepts input this func commits the data to the model (overwritten from QItemDelegate) + /// + void setModelData(QWidget *editor, QAbstractItemModel* model + , const QModelIndex &index) const; + + /// + /// \brief Fit an editor to some geometry (overwritten from QItemDelegate) + /// + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + protected: + + bool eventFilter( QObject *o, QEvent *e ); + + private slots: + /// + /// Invoked when the user accepts editor input, that is when he does not pushes ESC. + /// + void commitAndCloseEditor(); + void showColorDialog(); + void ComboBoxCurrentIndexChanged ( int index ) ; + void SpinBoxValueChanged ( const QString& value ) ; + +}; + +#endif /* QMITKPROPERTIESTABLEMODEL_H_ */ diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.cpp new file mode 100644 index 0000000000..545d858f4a --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.cpp @@ -0,0 +1,111 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkMapperSettingsWidget.h" + +#include + +QmitkMapperSettingsWidget::QmitkMapperSettingsWidget(QWidget*) : m_MaskMode(false), m_allowSampling(true) +{ + this->setupUi(this); + + connect(m_cbLinkFactors, SIGNAL(clicked()), this, SLOT(OnLinkSampleFactorChecked())); + connect(m_sbXFactor, SIGNAL(valueChanged(double)), this, SLOT(OnXFactorChanged(double))); +} + +void QmitkMapperSettingsWidget::ConfigureJobSettings(QmitkMappingJobSettings* settings) +{ + if (!settings) + { + return; + } + + settings->m_allowUndefPixels = m_groupAllowUndefPixels->isChecked(); + settings->m_paddingValue = m_sbPaddingValue->value(); + settings->m_allowUnregPixels = m_groupAllowUnregPixels->isChecked(); + settings->m_errorValue = m_sbErrorValue->value(); + settings->m_InterpolatorLabel = m_comboInterpolator->currentText().toStdString(); + + switch (m_comboInterpolator->currentIndex()) + { + case 0: + settings->m_InterpolatorType = mitk::ImageMappingInterpolator::NearestNeighbor; + break; + + case 1: + settings->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; + break; + + case 2: + settings->m_InterpolatorType = mitk::ImageMappingInterpolator::BSpline_3; + break; + + case 3: + settings->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Hamming; + break; + + case 4: + settings->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Welch; + break; + } +} + +void QmitkMapperSettingsWidget::OnXFactorChanged(double d) +{ + if (m_cbLinkFactors->isChecked()) + { + this->m_sbYFactor->setValue(d); + this->m_sbZFactor->setValue(d); + } +} + +void QmitkMapperSettingsWidget::OnLinkSampleFactorChecked() +{ + this->m_sbYFactor->setEnabled(!(this->m_cbLinkFactors->isChecked())); + this->m_sbZFactor->setEnabled(!(this->m_cbLinkFactors->isChecked())); + + if (m_cbLinkFactors->isChecked()) + { + this->m_sbYFactor->setValue(this->m_sbXFactor->value()); + this->m_sbZFactor->setValue(this->m_sbXFactor->value()); + } +} + +void QmitkMapperSettingsWidget::SetMaskMode(bool activeMask) +{ + if (activeMask != m_MaskMode) + { + if (activeMask) + { + this->m_comboInterpolator->setCurrentIndex(0); + this->m_sbErrorValue->setValue(0); + this->m_sbPaddingValue->setValue(0); + } + else + { + this->m_comboInterpolator->setCurrentIndex(1); + } + } + + m_MaskMode = activeMask; +} + + +void QmitkMapperSettingsWidget::AllowSampling(bool allow) +{ + m_allowSampling = allow; + m_groupActivateSampling->setVisible(allow); +} diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.h new file mode 100644 index 0000000000..e9739e9dee --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.h @@ -0,0 +1,68 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITK_MAPPER_SETTINGS_WIDGET_H +#define QMITK_MAPPER_SETTINGS_WIDGET_H + +#include + +#include "ui_QmitkMapperSettingsWidget.h" +#include + +struct QmitkMappingJobSettings; + +/** + * \class QmitkMapperSettingsWidget + * \brief Widget that views the information and profile of an algorithm stored in an DLLInfo object. + */ +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkMapperSettingsWidget : public QWidget, private Ui::QmitkMapperSettingsWidget +{ + Q_OBJECT + +public: + QmitkMapperSettingsWidget(QWidget* parent=0); + + /** + * Configures the passed settings according to the current state of the + * widget. + * \param pointer to a instance based on QmitkMappingJobSettings. + * \pre settings must point to a valid instance.. + */ + void ConfigureJobSettings(QmitkMappingJobSettings* settings); + +public Q_SLOTS: + /** + * \brief Slot that can be used to set the mode for the mapping settings. + * Mask mode allows only nearest neighbour interpolation. It is needed for exmample + * when mapping segmentations.*/ + void SetMaskMode(bool activeMask); + + /** + * \brief Slot that can be used to set the widget to a mode where super/sub sampling + * is allowed (true) or not (false).*/ + void AllowSampling(bool allow); + +protected Q_SLOTS: + void OnLinkSampleFactorChecked(); + + void OnXFactorChanged(double d); + +protected: + bool m_MaskMode; + bool m_allowSampling; +}; + +#endif // QmitkMapperSettingsWidget_H diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.ui b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.ui new file mode 100644 index 0000000000..aa2465cde2 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMapperSettingsWidget.ui @@ -0,0 +1,304 @@ + + + QmitkMapperSettingsWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 5 + + + 0 + + + + + + 0 + 0 + + + + + 50 + false + + + + <html><head/><body><p>Allows that pixels may not be defined in the mapped image because they are outside of the field of view of the used input image.</p><p>The pixels will be marked with the given padding value.</p><p>If unchecked the mapping will be aborted in a case of undefined pixels.</p></body></html> + + + Allow undefined pixels + + + false + + + true + + + + 5 + + + 9 + + + 5 + + + 9 + + + 5 + + + + + Padding value: + + + + + + + + 0 + 0 + + + + Pixel value that indicates pixels that are outside of the input image + + + -5000 + + + 5000 + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + <html><head/><body><p>Allows that pixels may not be registred because they are outside of the field of view of the used registration. The location in the correlated input image pixel(s) are therefore unkown. The pixels will be marked witrh the given error value.</p><p>If unchecked the mapping will be aborted in a case of unregistered pixels.</p></body></html> + + + Allow unregistred pixels + + + false + + + true + + + + 5 + + + 5 + + + 5 + + + + + Error value: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Value of pixels that cannot be registered because of an unsufficient field of view of the selected registration instance.</p></body></html> + + + -5000 + + + 5000 + + + + + + + + + + + 0 + 0 + + + + Interpolator: + + + + + + + true + + + <html><head/><body><p>Interpolation function that should be used to map the pixel values from the input image into the result image.</p></body></html> + + + 1 + + + + Nearest Neighbor + + + + + Linear + + + + + BSpline (3rd order) + + + + + Windowed Sinc (Hamming) + + + + + Windowed Sinc (Welch) + + + + + + + + + 0 + 0 + + + + Activate super/sub sampling + + + true + + + false + + + + 5 + + + + + <html><head/><body><p>Check to ensure that x, y and z dimension use the same sampling factor.</p></body></html> + + + linked factors + + + true + + + + + + + + + + 0 + 0 + + + + x: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Indicate the sampling factor to change the resolution.</p><p>2.0: doubled resolution; e.g. 100 pixels -&gt; 200 pixels and spacing 1 -&gt; spacing 0.5</p><p>0.5: half resolution; e.g. 100 pixels -&gt; 50 pixels and spacing 1 -&gt; spacing 2</p></body></html> + + + + + + + y: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + z: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.cpp new file mode 100644 index 0000000000..3fe5b5221c --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.cpp @@ -0,0 +1,177 @@ +/*=================================================================== + +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 "QmitkMappingJob.h" + +// Mitk +#include +#include +#include +#include +#include + +// Qt +#include + +#include + + +QmitkMappingJobSettings:: +QmitkMappingJobSettings() +{ + m_doGeometryRefinement = false; + m_MappedName = ""; + m_allowUndefPixels = true; + m_paddingValue = 0; + m_allowUnregPixels = true; + m_errorValue = 0; + m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; +}; + +const mitk::Image* +QmitkMappingJob:: +GetInputDataAsImage() const +{ + return dynamic_cast(m_spInputData.GetPointer()); +}; + +const mitk::PointSet* +QmitkMappingJob:: +GetInputDataAsPointSet() const +{ + return dynamic_cast(m_spInputData.GetPointer()); +}; + +const map::core::RegistrationBase* +QmitkMappingJob:: +GetRegistration() const +{ + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast + (m_spRegNode->GetData()); + + return dynamic_cast(wrapper->GetRegistration()); +}; + +void QmitkMappingJob::OnMapAlgorithmEvent(::itk::Object*, const itk::EventObject& event) +{ + const map::events::AnyMatchPointEvent* pMAPEvent = + dynamic_cast(&event); + + if (pMAPEvent) + { + emit AlgorithmInfo(QString::fromStdString(pMAPEvent->getComment())); + } +} + +QmitkMappingJob:: +QmitkMappingJob() +{ + m_spRefGeometry = NULL; + + m_spCommand = ::itk::MemberCommand::New(); + m_spCommand->SetCallbackFunction(this, &QmitkMappingJob::OnMapAlgorithmEvent); +}; + +QmitkMappingJob:: +~QmitkMappingJob() +{ +}; + +void +QmitkMappingJob:: +run() +{ + const mitk::Image* inputImage = this->GetInputDataAsImage(); + const mitk::PointSet* inputSet = this->GetInputDataAsPointSet(); + m_spMappedData = NULL; + + if (m_doGeometryRefinement) + { + try + { + mitk::Image::Pointer spResultImage = NULL; + + if (inputImage) + { + spResultImage = mitk::ImageMappingHelper::refineGeometry(inputImage, this->GetRegistration(), true); + } + + m_spMappedData = spResultImage; + + if (spResultImage.IsNotNull()) + { + emit MapResultIsAvailable(spResultImage.GetPointer(), this); + } + else + { + emit Error(QString("Error when when refining image geometry.")); + } + } + catch (std::exception& e) + { + emit Error(QString("Error when refining image geometry. Error description: ") + QString::fromLatin1( + e.what())); + } + catch (...) + { + emit Error(QString("Unknown error when refining image geometry.")); + } + + } + else + { + try + { + mitk::BaseData::Pointer spResultData = NULL; + + if (inputImage) + { + spResultData = mitk::ImageMappingHelper::map(this->GetInputDataAsImage(), this->GetRegistration(), + !(this->m_allowUndefPixels), this->m_paddingValue, this->m_spRefGeometry, + !(this->m_allowUnregPixels), this->m_errorValue, this->m_InterpolatorType).GetPointer(); + } + else if (inputSet) + { + mitk::PointSet::PointDataType errorValue; + errorValue.id = -1; + errorValue.pointSpec = mitk::PTUNDEFINED; + errorValue.selected = false; + spResultData = mitk::PointSetMappingHelper::map(inputSet, this->GetRegistration(), -1, false, + errorValue); + } + + if (spResultData.IsNotNull()) + { + emit MapResultIsAvailable(spResultData, this); + } + else + { + emit Error(QString("Error when mapping input data to result.")); + } + + m_spMappedData = spResultData; + } + catch (std::exception& e) + { + emit Error(QString("Error when mapping data. Error description: ") + QString::fromLatin1(e.what())); + } + catch (...) + { + emit Error(QString("Unkown error when mapping data.")); + } + + } +}; diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.h new file mode 100644 index 0000000000..1973e52093 --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkMappingJob.h @@ -0,0 +1,108 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef __QMITK_MAPPING_JOB_H +#define __QMITK_MAPPING_JOB_H + + +//QT +#include +#include + +// ITK +#include "itkCommand.h" + +// MatchPoint +#include + +//MITK +#include +#include +#include + +#include +#include + +struct MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkMappingJobSettings +{ +public: + /**Job name*/ + std::string m_MappedName; + /**Indicates of mapper should try to refine geometry (true) or map the data (false)*/ + bool m_doGeometryRefinement; + /**Indicates if the mapper should allow undefined pixels (true) or mapping should fail (false)*/ + bool m_allowUndefPixels; + /** Value of undefined pixels. Only relevant if m_allowUndefPixels is true. */ + double m_paddingValue; + /**Indicates if the mapper should allow pixels that are not covered by the registration (true) or mapping should fail (false)*/ + bool m_allowUnregPixels; + /** Value of unreged pixels. Only relevant if m_allowUnregPixels is true. */ + double m_errorValue; + /** Type of interpolator. Only relevant for images and if m_doGeometryRefinement is false. */ + mitk::ImageMappingInterpolator::Type m_InterpolatorType; + /** Display name of the interpolator*/ + std::string m_InterpolatorLabel; + + QmitkMappingJobSettings(); +}; + +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkMappingJob : public QObject, public QRunnable, public QmitkMappingJobSettings +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + QmitkMappingJob(); + ~QmitkMappingJob(); + + void run(); + + + +signals: + void Error(QString err); + /**Signal is emitted to return the mapped data itself. Use it if you are only interested in the mapped data*/ + void MapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job); + void AlgorithmInfo(QString info); + +public: + //Inputs + mitk::DataNode::Pointer m_spRegNode; + mitk::BaseData::ConstPointer m_spInputData; + mitk::NodeUIDType m_InputNodeUID; + mitk::BaseGeometry::Pointer m_spRefGeometry; + + const map::core::RegistrationBase* GetRegistration() const; + +protected: + + // mapped data. + mitk::BaseData::Pointer m_spMappedData; + + ::itk::MemberCommand::Pointer m_spCommand; + unsigned long m_ObserverID; + + //Helper functions + const mitk::Image* GetInputDataAsImage() const; + const mitk::PointSet* GetInputDataAsPointSet() const; + + void OnMapAlgorithmEvent(::itk::Object *, const itk::EventObject &event); +}; + +#endif + diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp new file mode 100644 index 0000000000..66fc17e43b --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp @@ -0,0 +1,217 @@ +/*=================================================================== + +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 "QmitkRegistrationJob.h" + +// Mitk +#include +#include +#include +#include +#include +#include +#include + +// Qt +#include + +// MatchPoint +#include +#include +#include +#include +#include + + +const mitk::Image* +QmitkRegistrationJob:: +GetTargetDataAsImage() const +{ + return dynamic_cast(m_spTargetData.GetPointer()); +}; + +const mitk::Image* +QmitkRegistrationJob:: +GetMovingDataAsImage() const +{ + return dynamic_cast(m_spMovingData.GetPointer()); +}; + +const map::algorithm::RegistrationAlgorithmBase* QmitkRegistrationJob::GetLoadedAlgorithm() const +{ + return m_spLoadedAlgorithm; +}; + + +void QmitkRegistrationJob::OnMapAlgorithmEvent(::itk::Object*, const itk::EventObject& event) +{ + const map::events::AlgorithmEvent* pAlgEvent = dynamic_cast + (&event); + const map::events::AlgorithmIterationEvent* pIterationEvent = + dynamic_cast(&event); + const map::events::AlgorithmWrapperEvent* pWrapEvent = + dynamic_cast(&event); + const map::events::AlgorithmResolutionLevelEvent* pLevelEvent = + dynamic_cast(&event); + + const map::events::InitializingAlgorithmEvent* pInitEvent = + dynamic_cast(&event); + const map::events::StartingAlgorithmEvent* pStartEvent = + dynamic_cast(&event); + const map::events::StoppingAlgorithmEvent* pStoppingEvent = + dynamic_cast(&event); + const map::events::StoppedAlgorithmEvent* pStoppedEvent = + dynamic_cast(&event); + const map::events::FinalizingAlgorithmEvent* pFinalizingEvent = + dynamic_cast(&event); + const map::events::FinalizedAlgorithmEvent* pFinalizedEvent = + dynamic_cast(&event); + + if (pInitEvent) + { + emit AlgorithmStatusChanged(QString("Initializing algorithm ...")); + } + else if (pStartEvent) + { + emit AlgorithmStatusChanged(QString("Starting algorithm ...")); + } + else if (pStoppingEvent) + { + emit AlgorithmStatusChanged(QString("Stopping algorithm ...")); + } + else if (pStoppedEvent) + { + emit AlgorithmStatusChanged(QString("Stopped algorithm ...")); + + if (! pStoppedEvent->getComment().empty()) + { + emit AlgorithmInfo(QString("Stopping condition: ") + QString::fromStdString( + pStoppedEvent->getComment())); + } + } + else if (pFinalizingEvent) + { + emit AlgorithmStatusChanged(QString("Finalizing algorithm and results ...")); + } + else if (pFinalizedEvent) + { + emit AlgorithmStatusChanged(QString("Finalized algorithm ...")); + } + else if (pIterationEvent) + { + const IIterativeAlgorithm* pIterative = dynamic_cast + (this->m_spLoadedAlgorithm.GetPointer()); + + map::algorithm::facet::IterativeAlgorithmInterface::IterationCountType count = 0; + bool hasCount = false; + + if (pIterative && pIterative->hasIterationCount()) + { + hasCount = true; + count = pIterative->getCurrentIteration(); + } + + emit AlgorithmIterated(QString::fromStdString(pIterationEvent->getComment()), hasCount, count); + } + else if (pLevelEvent) + { + const IMultiResAlgorithm* pResAlg = dynamic_cast + (this->m_spLoadedAlgorithm.GetPointer()); + + map::algorithm::facet::MultiResRegistrationAlgorithmInterface::ResolutionLevelCountType count = 0; + bool hasCount = false; + QString info = QString::fromStdString(pLevelEvent->getComment()); + + if (pResAlg && pResAlg->hasLevelCount()) + { + count = pResAlg->getCurrentLevel() + 1; + hasCount = true; + info = QString("Level #") + QString::number(pResAlg->getCurrentLevel() + 1) + QString(" ") + info; + } + + emit LevelChanged(info, hasCount, count); + } + else if (pAlgEvent && !pWrapEvent) + { + emit AlgorithmInfo(QString::fromStdString(pAlgEvent->getComment())); + } +} + +QmitkRegistrationJob:: +QmitkRegistrationJob(map::algorithm::RegistrationAlgorithmBase* pAlgorithm) +{ + m_MapEntity = false; + m_StoreReg = false; + m_ErrorOccured = false; + m_spLoadedAlgorithm = pAlgorithm; + m_JobName = "Unnamed RegJob"; + m_MovingNodeUID = "Missing moving UID"; + m_TargetNodeUID = "Missing target UID"; + + m_spTargetMask = NULL; + m_spMovingMask = NULL; + + m_spCommand = ::itk::MemberCommand::New(); + m_spCommand->SetCallbackFunction(this, &QmitkRegistrationJob::OnMapAlgorithmEvent); + m_ObserverID = m_spLoadedAlgorithm->AddObserver(::map::events::AlgorithmEvent(), m_spCommand); +}; + +QmitkRegistrationJob:: +~QmitkRegistrationJob() +{ + m_spLoadedAlgorithm->RemoveObserver(m_ObserverID); +}; + +void +QmitkRegistrationJob:: +run() +{ + try + { + mitk::MITKAlgorithmHelper helper(m_spLoadedAlgorithm); + mitk::MaskedAlgorithmHelper maskedHelper(m_spLoadedAlgorithm); + + //*@TODO Data Check and failure handle + helper.SetData(this->m_spMovingData, this->m_spTargetData); + maskedHelper.SetMasks(this->m_spMovingMask, this->m_spTargetMask); + + //perform registration + m_spResultRegistration = helper.GetRegistration(); + + //wrap the registration in a data node + if (m_spResultRegistration.IsNull()) + { + emit Error(QString("Error. No registration was determined. No results to store.")); + } + else + { + mitk::MAPRegistrationWrapper::Pointer spRegWrapper = mitk::MAPRegistrationWrapper::New(); + spRegWrapper->SetRegistration(m_spResultRegistration); + + emit RegResultIsAvailable(spRegWrapper, this); + } + } + catch (::std::exception& e) + { + emit Error(QString("Error while registering data. Details: ") + QString::fromLatin1(e.what())); + } + catch (...) + { + emit Error(QString("Unkown error when registering data.")); + } + + emit Finished(); +}; diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.h b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.h new file mode 100644 index 0000000000..e8ed30df6c --- /dev/null +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.h @@ -0,0 +1,107 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __QMITK_REGISTRATION_JOB_H +#define __QMITK_REGISTRATION_JOB_H + + +//QT +#include +#include + +// ITK +#include + +//MITK +#include +#include +#include "mitkUIDHelper.h" +#include + +// MatchPoint +#include +#include +#include +#include +#include + + +#include + +class MITKMATCHPOINTREGISTRATIONUI_EXPORT QmitkRegistrationJob : public QObject, public QRunnable +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + QmitkRegistrationJob(map::algorithm::RegistrationAlgorithmBase* pAlgorithm); + ~QmitkRegistrationJob(); + + void run(); + +signals: + void Finished(); + void Error(QString err); + void RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, const QmitkRegistrationJob* pJob); + void AlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration); + void LevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel); + void AlgorithmStatusChanged(QString info); + void AlgorithmInfo(QString info); + +public: + //Inputs + mitk::BaseData::ConstPointer m_spTargetData; + mitk::BaseData::ConstPointer m_spMovingData; + + mitk::Image::ConstPointer m_spTargetMask; + mitk::Image::ConstPointer m_spMovingMask; + + //job settings + bool m_MapEntity; + bool m_StoreReg; + bool m_ErrorOccured; + std::string m_JobName; + mitk::NodeUIDType m_TargetNodeUID; + mitk::NodeUIDType m_MovingNodeUID; + mitk::NodeUIDType m_TargetMaskNodeUID; + mitk::NodeUIDType m_MovingMaskNodeUID; + + const map::algorithm::RegistrationAlgorithmBase* GetLoadedAlgorithm() const; + +protected: + typedef map::algorithm::facet::IterativeAlgorithmInterface IIterativeAlgorithm; + typedef map::algorithm::facet::MultiResRegistrationAlgorithmInterface IMultiResAlgorithm; + + // Result registration. + map::core::RegistrationBase::Pointer m_spResultRegistration; + mitk::DataNode::Pointer m_spRegNode; + // mapped image. May be null if m_MapEntity is false. + mitk::DataNode::Pointer m_spMappedImageNode; + + ::itk::MemberCommand::Pointer m_spCommand; + unsigned long m_ObserverID; + map::algorithm::RegistrationAlgorithmBase::Pointer m_spLoadedAlgorithm; + + //Helper functions + const mitk::Image* GetTargetDataAsImage() const; + const mitk::Image* GetMovingDataAsImage() const; + + void OnMapAlgorithmEvent(::itk::Object *, const itk::EventObject &event); +}; + +#endif + diff --git a/Modules/MatchPointRegistrationUI/files.cmake b/Modules/MatchPointRegistrationUI/files.cmake new file mode 100644 index 0000000000..c87d37bc9f --- /dev/null +++ b/Modules/MatchPointRegistrationUI/files.cmake @@ -0,0 +1,36 @@ +set(CPP_FILES + Qmitk/QmitkRegistrationJob.cpp + Qmitk/QmitkMappingJob.cpp + Qmitk/QmitkFramesRegistrationJob.cpp + Qmitk/QmitkAlgorithmProfileViewer.cpp + Qmitk/QmitkAlgorithmSettingsConfig.cpp + Qmitk/QmitkMAPAlgorithmModel.cpp + Qmitk/QmitkAlgorithmListModel.cpp + Qmitk/QmitkMapPropertyDelegate.cpp + Qmitk/QmitkMapperSettingsWidget.cpp +) + +set(H_FILES + +) + +set(TPP_FILES +) + +set(UI_FILES + Qmitk/QmitkAlgorithmProfileViewer.ui + Qmitk/QmitkAlgorithmSettingsConfig.ui + Qmitk/QmitkMapperSettingsWidget.ui +) + +set(MOC_H_FILES + Qmitk/QmitkRegistrationJob.h + Qmitk/QmitkMappingJob.h + Qmitk/QmitkFramesRegistrationJob.h + Qmitk/QmitkAlgorithmProfileViewer.h + Qmitk/QmitkAlgorithmSettingsConfig.h + Qmitk/QmitkMAPAlgorithmModel.h + Qmitk/QmitkAlgorithmListModel.h + Qmitk/QmitkMapPropertyDelegate.h + Qmitk/QmitkMapperSettingsWidget.h +) diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 5e1599e1d4..62a0c5d924 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,78 +1,80 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. set(mitk_modules Core CommandLine AppUtil DCMTesting RDF LegacyIO DataTypesExt Overlays LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction ImageStatistics LegacyAdaptors SceneSerialization Gizmo GraphAlgorithms Multilabel ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation OpenViewCore QtWidgets QtWidgetsExt QtWidgetsWeb QmlItems SegmentationUI DiffusionImaging GPGPU OpenIGTLink IGTBase IGT CameraCalibration RigidRegistration RigidRegistrationUI DeformableRegistration DeformableRegistrationUI OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI US USUI DicomUI Simulation Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI VtkShaders DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware Classification TumorInvasionAnalysis + MatchPointRegistration + MatchPointRegistrationUI ) if(MITK_ENABLE_PIC_READER) list(APPEND mitk_modules IpPicSupportIO) endif() diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index c12529a2f0..8e07308e30 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,76 +1,83 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:OFF org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF #org.blueberry.test:ON #org.blueberry.uitest:ON #Testing/org.blueberry.core.runtime.tests:ON #Testing/org.blueberry.osgi.tests:ON org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.diffusionimaging:OFF org.mitk.simulation:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.registration:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.simulation:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.echotrack:OFF org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.multilabelsegmentation:ON + org.mitk.matchpoint.core.helper:OFF + org.mitk.gui.qt.matchpoint.algorithm.browser:OFF + org.mitk.gui.qt.matchpoint.algorithm.control:OFF + org.mitk.gui.qt.matchpoint.algorithm.batch:OFF + org.mitk.gui.qt.matchpoint.mapper:OFF + org.mitk.gui.qt.matchpoint.framereg:OFF + org.mitk.gui.qt.matchpoint.visualizer:OFF ) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/CMakeLists.txt new file mode 100644 index 0000000000..3479d83637 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_matchpoint_algorithm_batch) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_GUI_QT_MATCHPOINT_ALG_BATCH_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration MitkMatchPointRegistrationUI + PACKAGE_DEPENDS CTK|CTKCore +) \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..59a33479b0 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/Manual.dox @@ -0,0 +1,21 @@ +/** +\page org_mitk_gui_qt_matchpoint_algorithm_batch The MatchPoint Registration Batch Processor Plugin + +\imageMacro{map-icon-batch.png, "Icon of the MatchPoint Algorithm Batch Processor",3} + +\li \ref MAP_BATCH_Introduction +\li \ref MAP_BATCH_Contact +\li \ref MAP_BATCH_Usage + +\section MAP_BATCH_Introduction Introduction +This plugin is very similar to the MatchPoint algorithm controller plugin, but allows to register a set of selected input images in one batch run onto one selected target image. + +\section MAP_BATCH_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_BATCH_Usage Usage +Oops. Documentation is missing and to be done. +*/ + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/map-icon-batch.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/map-icon-batch.png new file mode 100644 index 0000000000..0365628f8a Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/UserManual/map-icon-batch.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..06eb4aca0c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk org.mitk + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_internal Internal + \ingroup org_mitk + + \brief This subcategory includes the internal classes of the org.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/files.cmake new file mode 100644 index 0000000000..4fcb45ce99 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/files.cmake @@ -0,0 +1,45 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.cpp + QmitkMatchPointBatchProcessor.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointBatchProcessor.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h + src/internal/QmitkMatchPointBatchProcessor.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.png + resources/icon_lock.png + resources/icon_unlock.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/manifest_headers.cmake new file mode 100644 index 0000000000..c8a93213a2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Registration Batch Processing") +set(Plugin-Version "0.2") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager org.mitk.matchpoint.core.helper) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/plugin.xml new file mode 100644 index 0000000000..67f17a3b21 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon.png new file mode 100644 index 0000000000..0365628f8a Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_lock.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_lock.png new file mode 100644 index 0000000000..7ca3d301a9 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_lock.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png new file mode 100644 index 0000000000..f6575c53af Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/readme_icon.txt b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/readme_icon.txt new file mode 100644 index 0000000000..07e12fdc30 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/readme_icon.txt @@ -0,0 +1,8 @@ +The icons icon_lock.png and icon_unlock.png are based on: + +Crystal Clear action exit.svg Image:Crystal Clear action lock1.png +Crystal Clear icon by Everaldo Coelho and YellowIcon. + +Distriubted over Wikimedia commons under LGPL. + +Thank you very much. diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.cpp new file mode 100644 index 0000000000..1a8eef6ed8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.cpp @@ -0,0 +1,742 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h" + +// Blueberry +#include +#include +#include +#include + +// Mitk +#include +#include +#include +#include +#include +#include +#include + +// Qt +#include +#include +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include +#include +#include + +// Qmitk +#include "QmitkMatchPointBatchProcessor.h" + + +const std::string QmitkMatchPointBatchProcessor::VIEW_ID = + "org.mitk.views.matchpoint.algorithm.batchprocessing"; + +QmitkMatchPointBatchProcessor::QmitkMatchPointBatchProcessor() + : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL) +{ + m_CanLoadAlgorithm = false; + m_ValidInputs = false; + m_Working = false; +} + +QmitkMatchPointBatchProcessor::~QmitkMatchPointBatchProcessor() +{ + // remove selection service + berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); + + if (s) + { + s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); + } +} + +void QmitkMatchPointBatchProcessor::SetFocus() +{ +} + +void QmitkMatchPointBatchProcessor::CreateConnections() +{ + // show first page + m_Controls.m_tabs->setCurrentIndex(0); + + // ------ + // Tab 1 - Shared library loading interface + // ------ + + connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); + + // ----- + // Tab 2 - Input + // ----- + connect(m_Controls.m_pbLockTarget, SIGNAL(clicked()), this, SLOT(OnLockTargetButtonPushed())); + connect(m_Controls.m_pbLockMoving, SIGNAL(clicked()), this, SLOT(OnLockMovingButtonPushed())); + + // ----- + // Tab 3 - Execution + // ----- + connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); +} + +const map::deployment::DLLInfo* QmitkMatchPointBatchProcessor::GetSelectedAlgorithmDLL() const +{ + return m_SelectedAlgorithmInfo; +} + +void QmitkMatchPointBatchProcessor::OnSelectedAlgorithmChanged() +{ + std::stringstream descriptionString; + + ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); + + if (!currentItemInfo) + { + Error(QString("No valid algorithm is selected. ABORTING.")); + return; + } + + m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); + + m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( + currentItemInfo->getAlgorithmUID().getName())); + + // enable loading + m_CanLoadAlgorithm = true; + this->UpdateAlgorithmSelectionGUI(); +} + +void QmitkMatchPointBatchProcessor::OnLoadAlgorithmButtonPushed() +{ + map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); + + if (!dllInfo) + { + Error(QString("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); + return; + } + + ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( + dllInfo->getLibraryFilePath()); + ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm + = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); + + if (tempAlgorithm.IsNull()) + { + Error(QString("Error. Cannot load selected algorithm.")); + return; + } + + this->m_LoadedAlgorithm = tempAlgorithm; + this->m_LoadedDLLHandle = tempDLLHandle; + + this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); + + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); + this->m_Controls.m_tabs->setCurrentIndex(1); + this->UpdateAlgorithmSelectionGUI(); +} + +void QmitkMatchPointBatchProcessor::OnLockTargetButtonPushed() +{ + if (this->m_Controls.m_pbLockTarget->isChecked()) + { + if (this->m_spSelectedTargetNode.IsNotNull()) + { + this->m_spSelectedTargetNode->SetSelected(false); + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureRegistrationControls(); +} + +void QmitkMatchPointBatchProcessor::OnLockMovingButtonPushed() +{ + if (this->m_Controls.m_pbLockMoving->isChecked()) + { + if (!this->m_selectedMovingNodes.empty()) + { + for (NodeListType::const_iterator pos = m_selectedMovingNodes.begin(); + pos != m_selectedMovingNodes.end(); ++pos) + { + (*pos)->SetSelected(false); + } + + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureRegistrationControls(); +} + + +void QmitkMatchPointBatchProcessor::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); + + m_Controls.m_teLog->append(QString("") + msg + QString("")); +} + +void QmitkMatchPointBatchProcessor::UpdateAlgorithmSelectionGUI() +{ + m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); +} + +void QmitkMatchPointBatchProcessor::CreateQtPartControl(QWidget* parent) +{ + + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + m_Parent = parent; + + m_AlgorithmSelectionListener.reset(new + berry::SelectionChangedAdapter(this, + &QmitkMatchPointBatchProcessor::OnAlgorithmSelectionChanged)); + + // register selection listener + GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( + m_AlgorithmSelectionListener.data()); + + this->CreateConnections(); + this->UpdateAlgorithmSelectionGUI(); + this->CheckInputs(); + this->ConfigureProgressInfos(); + this->ConfigureRegistrationControls(); + + berry::ISelection::ConstPointer selection = + GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); + + this->UpdateAlgorithmSelection(selection); +} + +void QmitkMatchPointBatchProcessor::CheckInputs() +{ + bool validMoving = false; + bool validTarget = false; + + NodeListType dataNodes = this->GetSelectedDataNodes(); + + + //first set the internal nodes according to selection + if (!m_Controls.m_pbLockTarget->isChecked()) + { + mitk::DataNode::Pointer targetNode = NULL; + + if (dataNodes.size() > 0) + { + targetNode = dataNodes.front(); + dataNodes.pop_front(); + + mitk::Image* targetImage = dynamic_cast(targetNode->GetData()); + + if (targetImage) + { + if (m_LoadedAlgorithm.IsNotNull()) + { + if (targetImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions()) + { + m_Controls.m_lbTargetName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D needed")); + } + else + { + validTarget = true; + } + } + else + { + validTarget = true; + } + + if (validTarget) + { + m_Controls.m_lbTargetName->setText(QString::fromStdString(targetNode->GetName())); + } + } + } + + this->m_spSelectedTargetNode = targetNode; + } + else + { + validTarget = true; + } + + if (this->m_spSelectedTargetNode.IsNull()) + { + m_Controls.m_lbTargetName->setText(QString("no data selected!")); + } + + if (!m_Controls.m_pbLockMoving->isChecked()) + { + m_selectedMovingNodes.clear(); + this->m_Controls.m_listMovingNames->clear(); + + if (dataNodes.size() > 0) + { + for (NodeListType::const_iterator pos = dataNodes.begin(); pos != dataNodes.end(); ++pos) + { + this->m_Controls.m_listMovingNames->addItem(QString::fromStdString((*pos)->GetName())); + } + } + + m_selectedMovingNodes = dataNodes; + validMoving = !m_selectedMovingNodes.empty(); + } + else + { + validMoving = true; + } + + if (this->m_selectedMovingNodes.size() == 0) + { + this->m_Controls.m_listMovingNames->addItem(QString("no data selected!")); + } + + this->m_Controls.m_pbLockMoving->setEnabled(this->m_selectedMovingNodes.size() > 0); + this->m_Controls.m_pbLockTarget->setEnabled(this->m_spSelectedTargetNode.IsNotNull()); + + m_ValidInputs = validMoving && validTarget; +} + +mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPointBatchProcessor::GetRegNodes() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); + mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); + + for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); + ++pos) + { + if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + result->push_back(*pos); + } + } + + return result; +} + +QList QmitkMatchPointBatchProcessor::GetSelectedDataNodes() +{ + NodeListType nodes = m_currentlySelectedNodes; //this->GetDataManagerSelection(); + NodeListType result; + + + /**@TODO rework to use mitk node filter mechanism*/ + for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) + { + mitk::Image* image = dynamic_cast((*pos)->GetData()); + + if (image) + { + result.push_back(*pos); + } + } + + return result; +} + +std::string QmitkMatchPointBatchProcessor::GetDefaultRegJobName() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); + mitk::DataStorage::SetOfObjects::ElementIdentifier estimatedIndex = nodes->Size(); + + bool isUnique = false; + std::string result = "Unnamed Reg"; + + while (!isUnique) + { + ++estimatedIndex; + result = "Reg #" +::map::core::convert::toStr(estimatedIndex); + isUnique = this->GetDataStorage()->GetNamedNode(result) == NULL; + } + + return result; +} + +void QmitkMatchPointBatchProcessor::ConfigureRegistrationControls() +{ + m_Controls.m_pageSelection->setEnabled(!m_Working); + m_Controls.m_leRegJobName->setEnabled(!m_Working); + + m_Controls.m_pbStartReg->setEnabled(false); + + /**@TODO reactivate as soon as crex processor allows to stop batch processing.*/ + //m_Controls.m_pbStopReg->setEnabled(false); + //m_Controls.m_pbStopReg->setVisible(false); + + if (m_LoadedAlgorithm.IsNotNull()) + { + m_Controls.m_pageSettings->setEnabled(!m_Working); + m_Controls.m_pageExecution->setEnabled(true); + m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); + ///////////////////////////////////////////// + + const IStoppableAlgorithm* pIterativ = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + /**@TODO reactivate as soon as crex processor allows to stop batch processing.*/ + //if (pIterativ) + //{ + // m_Controls.m_pbStopReg->setVisible(pIterativ->isStoppable()); + //} + + ////if the stop button is set to visible and the algorithm is working -> + ////then the algorithm is stoppable, thus enable the button. + //m_Controls.m_pbStopReg->setEnabled(m_Controls.m_pbStopReg->isVisible() && m_Working); + + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); + } + else + { + m_Controls.m_pageSettings->setEnabled(false); + m_Controls.m_pageExecution->setEnabled(false); + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString("no algorithm loaded!")); + } + + if (!m_Working) + { + this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultRegJobName())); + } +} + +void QmitkMatchPointBatchProcessor::ConfigureProgressInfos() +{ + const IIterativeAlgorithm* pIterative = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + const IMultiResAlgorithm* pMultiRes = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + m_Controls.m_progBarIteration->setVisible(pIterative); + m_Controls.m_lbProgBarIteration->setVisible(pIterative); + + + if (pIterative) + { + QString format = "%p% (%v/%m)"; + + if (!pIterative->hasMaxIterationCount()) + { + format = "%v"; + m_Controls.m_progBarIteration->setMaximum(0); + } + else + { + m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); + } + + m_Controls.m_progBarIteration->setFormat(format); + } + + if (pMultiRes) + { + m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); + + } + else + { + m_Controls.m_progBarLevel->setMaximum(1); + } + + m_Controls.m_progBarJob->setMaximum(this->m_selectedMovingNodes.size()); + m_Controls.m_progBarJob->reset(); + + m_Controls.m_progBarIteration->reset(); + m_Controls.m_progBarLevel->reset(); +} + +void QmitkMatchPointBatchProcessor::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes) +{ + m_currentlySelectedNodes = nodes; + + if (!m_Working) + { + CheckInputs(); + ConfigureRegistrationControls(); + } +} + +void QmitkMatchPointBatchProcessor::OnStartRegBtnPushed() +{ + this->m_Working = true; + + //////////////////////////////// + //configure GUI + this->ConfigureProgressInfos(); + + this->ConfigureRegistrationControls(); + + if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) + { + this->m_Controls.m_teLog->clear(); + } + + this->m_nextNodeToSpawn = 0; + + SpawnNextJob(); +} + +bool QmitkMatchPointBatchProcessor::SpawnNextJob() +{ + if (this->m_nextNodeToSpawn < this->m_selectedMovingNodes.size()) + { + QmitkRegistrationJob* pJob = new QmitkRegistrationJob(m_LoadedAlgorithm); + pJob->setAutoDelete(true); + + pJob->m_spTargetData = this->m_spSelectedTargetNode->GetData(); + pJob->m_spMovingData = this->m_selectedMovingNodes[m_nextNodeToSpawn]->GetData(); + pJob->m_TargetNodeUID = mitk::EnsureUID(this->m_spSelectedTargetNode); + pJob->m_MovingNodeUID = mitk::EnsureUID(this->m_selectedMovingNodes[m_nextNodeToSpawn]); + + QString jobName = m_Controls.m_leRegJobName->text() + QString(" ") + QString::fromStdString( + this->m_selectedMovingNodes[m_nextNodeToSpawn]->GetName()); + pJob->m_JobName = jobName.toStdString(); + + pJob->m_StoreReg = m_Controls.m_checkStoreReg->checkState() == Qt::Checked; + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); + connect(pJob, SIGNAL(RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, + const QmitkRegistrationJob*)), this, + SLOT(OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), + Qt::BlockingQueuedConnection); + connect(pJob, SIGNAL(MapResultNodeIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); + connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, + SLOT(OnAlgorithmStatusChanged(QString))); + connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, + SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); + connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, + bool, unsigned long))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); + + this->m_nextNodeToSpawn++; + return true; + } + + return false; +} + +void QmitkMatchPointBatchProcessor::OnRegJobFinished() +{ + if (SpawnNextJob()) + { + m_Controls.m_teLog->append( + QString("

Commencing new registration job...

")); + m_Controls.m_progBarJob->setValue(this->m_nextNodeToSpawn); + } + else + { + this->m_Working = false; + + this->GetRenderWindowPart()->RequestUpdate(); + + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); + } +}; + + +void QmitkMatchPointBatchProcessor::OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer + spResultRegistration, const QmitkRegistrationJob* pRegJob) +{ + mitk::DataNode::Pointer spResultRegistrationNode = mitk::generateRegistrationResultNode( + pRegJob->m_JobName, spResultRegistration, pRegJob->GetLoadedAlgorithm()->getUID()->toStr(), + pRegJob->m_MovingNodeUID, pRegJob->m_TargetNodeUID); + + if (pRegJob->m_StoreReg) + { + m_Controls.m_teLog->append( + QString(" Storing registration object in data manager ... ")); + + this->GetDataStorage()->Add(spResultRegistrationNode); + this->GetRenderWindowPart()->RequestUpdate(); + } + + if (m_Controls.m_checkMapEntity->checkState() == Qt::Checked) + { + QmitkMappingJob* pMapJob = new QmitkMappingJob(); + pMapJob->setAutoDelete(true); + + pMapJob->m_spInputData = pRegJob->m_spMovingData; + pMapJob->m_InputNodeUID = pRegJob->m_MovingNodeUID; + pMapJob->m_spRegNode = spResultRegistrationNode; + pMapJob->m_doGeometryRefinement = false; + pMapJob->m_spRefGeometry = pRegJob->m_spTargetData->GetGeometry()->Clone().GetPointer(); + + pMapJob->m_MappedName = pRegJob->m_JobName + std::string(" mapped"); + pMapJob->m_allowUndefPixels = true; + pMapJob->m_paddingValue = 100; + pMapJob->m_allowUnregPixels = true; + pMapJob->m_errorValue = 200; + pMapJob->m_InterpolatorLabel = "Linear Interpolation"; + pMapJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; + + connect(pMapJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); + connect(pMapJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + Qt::BlockingQueuedConnection); + connect(pMapJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); + + m_Controls.m_teLog->append( + QString("Started mapping input data...")); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pMapJob); + } +}; + +void QmitkMatchPointBatchProcessor::OnMapJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPointBatchProcessor::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, + const QmitkMappingJob* job) +{ + m_Controls.m_teLog->append(QString("Mapped entity stored. Name: ") + + QString::fromStdString(job->m_MappedName) + QString("")); + + mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, + spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputNodeUID, + job->m_doGeometryRefinement, job->m_InterpolatorLabel); + this->GetDataStorage()->Add(spMappedNode); + this->GetRenderWindowPart()->RequestUpdate(); +}; + +void QmitkMatchPointBatchProcessor::OnStopRegBtnPushed() +{ + if (m_LoadedAlgorithm.IsNotNull()) + { + IStoppableAlgorithm* pIterativ = dynamic_cast(m_LoadedAlgorithm.GetPointer()); + + if (pIterativ && pIterativ->isStoppable()) + { + if (pIterativ->stopAlgorithm()) + { + + } + else + { + + } + + /**@TODO reactivate as soon as crex processor allows to stop batch processing.*/ + //m_Controls.m_pbStopReg->setEnabled(false); + } + else + { + } + } +} + +void QmitkMatchPointBatchProcessor::OnRegJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPointBatchProcessor::OnAlgorithmIterated(QString info, bool hasIterationCount, + unsigned long currentIteration) +{ + if (hasIterationCount) + { + m_Controls.m_progBarIteration->setValue(currentIteration); + } + + m_Controls.m_teLog->append(info); +}; + +void QmitkMatchPointBatchProcessor::OnLevelChanged(QString info, bool hasLevelCount, + unsigned long currentLevel) +{ + if (hasLevelCount) + { + m_Controls.m_progBarLevel->setValue(currentLevel); + } + + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPointBatchProcessor::OnAlgorithmStatusChanged(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString(" ")); +}; + +void QmitkMatchPointBatchProcessor::OnAlgorithmInfo(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPointBatchProcessor::UpdateAlgorithmSelection(berry::ISelection::ConstPointer + selection) +{ + mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = + selection.Cast(); + + if (currentSelection) + { + mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = + currentSelection->GetSelectedAlgorithmInfo(); + + if (!infoVector.empty()) + { + // only the first selection is of interest, the rest will be skipped. + this->m_SelectedAlgorithmInfo = infoVector[0]; + } + } + + this->OnSelectedAlgorithmChanged(); +}; + +void QmitkMatchPointBatchProcessor::OnAlgorithmSelectionChanged(const + berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection) +{ + // check for null selection + if (selection.IsNull()) + { + return; + } + + if (sourcepart != this) + { + UpdateAlgorithmSelection(selection); + } +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.h new file mode 100644 index 0000000000..abf1cd2569 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.h @@ -0,0 +1,201 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + + +#ifndef __Q_MITK_MATCHPOINT_BATCH_PROCESSOR_H +#define __Q_MITK_MATCHPOINT_BATCH_PROCESSOR_H + +#include + +#include + +#include "ui_QmitkMatchPointBatchProcessor.h" + +// MatchPoint +#include +#include +#include +#include +#include +#include + +#include + +class QmitkRegistrationJob; +class QmitkMappingJob; + +/*! +\brief View for registration batch processing based on MatchPoint + +This view composes the GUI and implements the business logic needed to allow registration +batch processing (one target, many moving images). + +\ingroup ${plugin_target}_internal +*/ +class QmitkMatchPointBatchProcessor : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPointBatchProcessor) + + QmitkMatchPointBatchProcessor(); + ~QmitkMatchPointBatchProcessor(); + +protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + /// \brief Called when the user clicks the GUI button + + void OnLoadAlgorithmButtonPushed(); + void OnSelectedAlgorithmChanged(); + + void OnLockMovingButtonPushed(); + void OnLockTargetButtonPushed(); + + void OnStartRegBtnPushed(); + void OnStopRegBtnPushed(); + + void OnRegJobError(QString err); + void OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, + const QmitkRegistrationJob* pRegJob); + void OnRegJobFinished(); + void OnMapJobError(QString err); + void OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job); + void OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration); + void OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel); + void OnAlgorithmStatusChanged(QString info); + void OnAlgorithmInfo(QString info); + +protected: + virtual void CreateQtPartControl(QWidget* parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& nodes); + +private: + typedef QList NodeListType; + + /** Spawns a registration job for the next selected moving node (see m_nextNodeToSpawn). + * If no nodes are left, no job will be spawned and false is returned. + * If at least one node is left, a job will be spawned, m_nextNodeToSpawn will be incremented + * and true will be returned.*/ + bool SpawnNextJob(); + + /** + * @brief Adapt the visibility of GUI elements depending on the current data loaded + */ + void UpdateAlgorithmSelectionGUI(); + + + void Error(QString msg); + + void UpdateAlgorithmList(); + + /** + * checks if appropriated nodes are selected in the data manager. If nodes are selected, + * they are stored in m_spSelectedTargetNode and m_selectedMovingNodes. It also sets the info labels accordingly.*/ + void CheckInputs(); + + /** + * Updates the state of registration control buttons. Regarding to selected + * inputs, loaded algorithm and its state.*/ + void ConfigureRegistrationControls(); + + /** + * Configures the progress bars according to the chosen algorithm. + */ + void ConfigureProgressInfos(); + + /** Methods returns a list of all nodes selected in the data manager that do + * NOT contain registration wrappers. The list may be empty if nothing is + * selected or no appropriate data node is selected.*/ + NodeListType GetSelectedDataNodes(); + + /** Methods returns a list of all nodes in the data manager containing a registration wrapper. + * The list may be empty.*/ + mitk::DataStorage::SetOfObjects::Pointer GetRegNodes() const; + + /** Returns a proposal for a (unique) default reg job name */ + std::string GetDefaultRegJobName() const; + + /** Returns the Pointer to the DLL info of the algorithm currently selected by the system. + The info is received via m_SelectionListener. + @return If there is no item selected the returning pointer + will be null. + */ + const map::deployment::DLLInfo* GetSelectedAlgorithmDLL() const; + + //! [Qt Selection Listener method and pointer] + /** + * @brief Method of berry::ISelectionListener that implements the selection listener functionality. + * @param sourcepart The workbench part responsible for the selection change. + * @param selection This parameter holds the current selection. + * + * @see ISelectionListener + */ + void OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection); + + void UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection); + + friend struct berry::SelectionChangedAdapter; + /** @brief this pointer holds the algorithm selection listener */ + QScopedPointer m_AlgorithmSelectionListener; + + ::map::deployment::DLLHandle::Pointer m_LoadedDLLHandle; + ::map::algorithm::RegistrationAlgorithmBase::Pointer m_LoadedAlgorithm; + ::map::deployment::DLLInfo::ConstPointer m_SelectedAlgorithmInfo; + + typedef map::algorithm::facet::IterativeAlgorithmInterface IIterativeAlgorithm; + typedef map::algorithm::facet::MultiResRegistrationAlgorithmInterface IMultiResAlgorithm; + typedef map::algorithm::facet::StoppableAlgorithmInterface IStoppableAlgorithm; + + /**All selected nodes stored by OnSelectionChanged()*/ + NodeListType m_currentlySelectedNodes; + + mitk::DataNode::Pointer m_spSelectedTargetNode; + NodeListType m_selectedMovingNodes; + /**indicates the next selected moving nodes that should be spawned as job.*/ + unsigned int m_nextNodeToSpawn; + + // boolean variables to control visibility of GUI elements + bool m_CanLoadAlgorithm; + bool m_ValidInputs; + bool m_Working; + + QWidget* m_Parent; + Ui::MatchPointAdvancedControls m_Controls; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.ui b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.ui new file mode 100644 index 0000000000..4cc5cadd08 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/QmitkMatchPointBatchProcessor.ui @@ -0,0 +1,697 @@ + + + MatchPointAdvancedControls + + + + 0 + 0 + 301 + 737 + + + + + 5 + + + 5 + + + + + Loaded algorithm: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + true + + + + 200 + 0 + + + + 2 + + + + + 0 + 0 + 146 + 125 + + + + Algorithm selection + + + + 5 + + + 5 + + + + + + 75 + true + + + + Load an algorithm + + + + + + + Algorithm browser selection: + + + + + + + Load selected algorithm + + + + + + + true + + + false + + + Selected algorithm information: + + + true + + + 0 + + + -1 + + + + + + + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + TextLabel + + + + + label_Heading1 + m_teAlgorithmDetails + label_algo + label_algoInfo + m_pbLoadSelected + m_lbSelectedAlgorithm + + + + + 0 + 0 + 112 + 152 + + + + Input + + + + 5 + + + 5 + + + + + Target image: + + + + + + + 3 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Moving image that should be mapped... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the selected moving image to do not change anymore + + + + + + + :/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png + :/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_lock.png:/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png + + + true + + + false + + + + + + + + + Moving image(s): + + + + + + + 3 + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 1000 + + + + Lock the reference image + + + + + + + :/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png + :/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_lock.png:/org.mitk.gui.qt.matchpoint.algorithm.batch/resources/icon_unlock.png + + + true + + + false + + + + + + + + + + + 0 + 0 + 291 + 581 + + + + Execution + + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 75 + true + + + + Perform Registration + + + + + + + Registration job name: + + + + + + + Name of the resulting mapped image + + + Unnamed RegJob + + + + + + + Store registration + + + true + + + + + + + Generate + store mapped result + + + true + + + + + + + + + Start + + + + + + + + + + 0 + 0 + + + + Progress + + + false + + + + + + Job: + + + + + + + 100 + + + 24 + + + false + + + %v/%m + + + + + + + Resolution level: + + + + + + + 100 + + + 24 + + + false + + + %v/%m + + + + + + + Iterations: + + + + + + + 100 + + + 24 + + + false + + + %p% (%v/%m) + + + + + + + Log: + + + + + + + + 0 + 0 + + + + + 9 + + + + true + + + QTextEdit::NoWrap + + + true + + + + + + + Clear log on algorithm start + + + + + + + + + + + + 0 + 0 + 260 + 28 + + + + Settings + + + + 5 + + + 5 + + + + + + 75 + true + + + + Configure algorithm parameters + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + + + + + + + + + + QmitkAlgorithmProfileViewer + QWidget +

QmitkAlgorithmProfileViewer.h
+ + + QmitkAlgorithmSettingsConfig + QWidget +
QmitkAlgorithmSettingsConfig.h
+
+ + + + + + 5 + + + 5 + + + true + + + true + + + true + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.cpp new file mode 100644 index 0000000000..df5eb98816 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.cpp @@ -0,0 +1,43 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h" + +#include "QmitkMatchPointBatchProcessor.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator::start( + ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPointBatchProcessor, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator::stop( + ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h new file mode 100644 index 0000000000..a278e18769 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.batch/src/internal/org_mitk_gui_qt_matchpoint_algorithm_batch_Activator.h @@ -0,0 +1,43 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator_h +#define org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_algorithm_batchprocessing") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator + +#endif // org_mitk_gui_qt_matchpoint_algorithm_batchprocessing_Activator_h diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/CMakeLists.txt new file mode 100644 index 0000000000..254ab499ae --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_matchpoint_algorithm_browser) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITKGUI_QT_MATCHPOINT_ALG_BROWSER_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration MitkMatchPointRegistrationUI + PACKAGE_DEPENDS CTK|CTKCore +) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..4b34606932 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/Manual.dox @@ -0,0 +1,58 @@ +/** +\page org_mitk_gui_qt_matchpoint_algorithm_browser The MatchPoint Algorithm Browser View + +\imageMacro{map-icon-browser.png, "Icon of the MatchPoint Algorithm Browser", 3} + +\li \ref MAP_BROWSER_Introduction +\li \ref MAP_BROWSER_Contact +\li \ref MAP_BROWSER_Usage +\li \ref MAP_BROWSER_Profile + +\section MAP_BROWSER_Introduction Introduction +This view offers the user a way to search for available registration algorithms and select them for +further usage by other views (e.g. MatchPoint Algorithm Control \ref org_mitk_gui_qt_algorithm_control). + +\section MAP_BROWSER_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_BROWSER_Usage Usage +\remark If you see no algorithms available by the browser, please check the search paths which can be configured at the MatchPoint preference page (Ctrl+P). +DIPP-User: You should activate at least "scan installation directory" to see the algorithms delivered with the DIPP installer. + +The basic idea of the browser is that you can use this view as central place to search for suitable algorithms. If you select an algorithm you can see its profile in the lower part of the view. +If a algorithm is selected all other views (e.g. \ref org_mitk_gui_qt_algorithm_control or \ref de_dkfz_dwi_gui_qt_crex) which use registration algorithms will be notified and allow to choose the selected algorithm for usage. +\imageMacro{browser.png, "View of the browser with the list of available algorithm and the profile area",14} + +\remark You haven't found a fitting registration algorithm? Please have a look at the registration repository at our SBR share point (http://intracoop/sites/sbr/Lists/RegRepository/default.aspx) +or contact us (dipp@dkfz.de). + +\section MAP_BROWSER_Profile Profile info +In the following a short information about the different properties classified in the profile.\n + +
    +
  • UID Unique identifier for the registration algorithm (e.g. used in the library; may not be "human readable/understandable")
  • +
  • Author Name of the author(s) that has (have) developed the algorithm.
  • +
  • Terms Terms of usage for the algorithm.
  • +
  • Data type The type of date which is used by the algorithm to determine the registration. E.g. Image, point set, contour or surface
  • +
  • Computation style Specifies of the algorithm determines the registration by an iterative optimization process or analytically (e.g. closed form solution). +Deterministic Specifies if the algorithm is deterministic (same input -> same output) or stochastic (e.g. by sampling the image while determining the registration). Results of stochastic algorithm may vary (slightly) because of their random aspect. +Resolution style Defines if the algorithm uses a multi resolution/scale approach.
  • +
  • Dim (Moving) Number of dimensions of the frame of reference within which the data is defined that should be registered.
  • +
  • Modality (Moving) Modality of the moving entity (image). Thus the frame of reference where the registration should map from. E.g. CT, MRI, PET
  • +
  • Dim (Target) Number of dimensions of the frame of reference into which the data should be mapped.
  • +
  • Modality (Target) Modality of the target entity (image). Thus the frame of reference where the registration should map into. E.g. CT, MRI, PET
  • +
  • Subject Defines if the algorithm was developed to register data of the same subject (intrasubject), to register two subjects (intersubject) or to register onto an atlas.
  • +
  • Object Specifies for which "part" of the anatomy the algorithm was developed for.
  • +
  • Transformation model Specifies the type of transformation used by the algorithm. E.g.: affine, b-spline, non-rigid.
  • +
  • Transformation domain Defines it the transformation operates globally (e.g. Matrix) or locally (e.g. vector field).
  • +
  • Optimization strategy The used optimization strategy (if an optimizer is used).
  • +
  • Metric The cost function/metric that is used by the optimizer (if an optimizer is used).
  • +
  • Citation/Reference Reference to literature that contains information about the algorithm and should be used to cite the algorithm.
  • +
  • Literature Secondary literature regarding the algorithm or used concepts in the algorithm. Use the field "Citation/Reference" for the literature that should be cited when using the algorithm.
  • +
  • Contact Internal contact for questions regarding the algorithm.
  • +
+ +*/ + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/browser.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/browser.png new file mode 100644 index 0000000000..6067f5fac1 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/browser.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/map-icon-browser.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/map-icon-browser.png new file mode 100644 index 0000000000..55ca4e7494 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/UserManual/map-icon-browser.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..06eb4aca0c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk org.mitk + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_internal Internal + \ingroup org_mitk + + \brief This subcategory includes the internal classes of the org.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/files.cmake new file mode 100644 index 0000000000..280e75be68 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/files.cmake @@ -0,0 +1,45 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.cpp + QmitkMatchPointBrowser.cpp + mitkAlgorithmInfoSelectionProvider.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointBrowserControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h + src/internal/QmitkMatchPointBrowser.h + src/internal/mitkAlgorithmInfoSelectionProvider.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.xpm + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/manifest_headers.cmake new file mode 100644 index 0000000000..ba5d50fb87 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Algorithm Browser") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager org.mitk.matchpoint.core.helper) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/plugin.xml new file mode 100644 index 0000000000..dc24da9a94 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/resources/icon.xpm b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/resources/icon.xpm new file mode 100644 index 0000000000..5eda35daa7 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/resources/icon.xpm @@ -0,0 +1,230 @@ +/* XPM */ +static char *mapiconbrowse[] = { +/* columns rows colors chars-per-pixel */ +"32 32 192 2", +" c #1B1A1B", +". c #2C2B2B", +"X c #2A3131", +"o c #3C3B3A", +"O c #623C3C", +"+ c #424243", +"@ c #4C4C4C", +"# c #514F4C", +"$ c #53514E", +"% c #525252", +"& c #585552", +"* c #5B5B5B", +"= c #666665", +"- c #696765", +"; c #6F6E6D", +": c #706D6A", +"> c #72716F", +", c #6E7170", +"< c #767574", +"1 c #7A7978", +"2 c #850100", +"3 c #8D0702", +"4 c #8C0801", +"5 c #9D0704", +"6 c #961207", +"7 c #B30000", +"8 c #A11D03", +"9 c #B22501", +"0 c #BB2602", +"q c #B12801", +"w c #B13216", +"e c #C60000", +"r c #C62000", +"t c #C12802", +"y c #BE4F22", +"u c #C1481F", +"i c #CB5712", +"p c #EC6D0B", +"a c #FB7909", +"s c #CC4622", +"d c #C74D21", +"f c #CC4B21", +"g c #D24D21", +"h c #DA4B28", +"j c #CF7628", +"k c #FF9917", +"l c #FF9619", +"z c #FFA025", +"x c #FFB332", +"c c #FFC738", +"v c #81807E", +"b c #F1C74F", +"n c #FAD04E", +"m c #FFE24E", +"M c #FFE450", +"N c #FFEA53", +"B c #FCEC5D", +"V c #FCEF60", +"C c #0027B5", +"Z c #042BB7", +"A c #0F34B9", +"S c #1E40BE", +"D c #2143BF", +"F c #677CA9", +"G c #627CB6", +"H c #2D4DC2", +"J c #3655C5", +"K c #3957C6", +"L c #425FC8", +"P c #4561C9", +"I c #546ECD", +"U c #637BD2", +"Y c #7E8892", +"T c #6C83B3", +"R c #7589C5", +"E c #6C82D4", +"W c #738DD4", +"Q c #7AA4DD", +"! c #6990E3", +"~ c #7A96E1", +"^ c #7D99E6", +"/ c #789BEF", +"( c #6EA0E9", +") c #858482", +"_ c #85888C", +"` c #8C8B8A", +"' c #908E8B", +"] c #93918E", +"[ c #848D96", +"{ c #848C99", +"} c #8E9093", +"| c #979695", +" . c #979E9E", +".. c #98999A", +"X. c #A4A09B", +"o. c #949BA1", +"O. c #879EB3", +"+. c #87A2BD", +"@. c #99ACBC", +"#. c #AEA5A7", +"$. c #ADABA8", +"%. c #B0AFAC", +"&. c #B4B1AB", +"*. c #A0A5B6", +"=. c #A6ABB0", +"-. c #BAB9B9", +";. c #E0B791", +":. c #E7BD96", +">. c #C1BEBC", +",. c #D9DE9D", +"<. c #C6C4BC", +"1. c #F1F4B2", +"2. c #8799DC", +"3. c #8D9EDE", +"4. c #9CB4C8", +"5. c #90A1DF", +"6. c #B7B9C2", +"7. c #B7BBC9", +"8. c #829CE4", +"9. c #97A9E0", +"0. c #99A9E1", +"q. c #8EB8EB", +"w. c #9ABEE3", +"e. c #82ACFA", +"r. c #83B1F9", +"t. c #8AB4FA", +"y. c #88BCFD", +"u. c #ABB8E7", +"i. c #B2BFE6", +"p. c #ADC0CD", +"a. c #BFC8C8", +"s. c #9FC7ED", +"d. c #8DC6FF", +"f. c #96CBFF", +"g. c #9BCDFF", +"h. c #9FD0FF", +"j. c #A2C7EB", +"k. c #B3C2EC", +"l. c #A3C1FC", +"z. c #A7C8FD", +"x. c #A8CFFF", +"c. c #A3D2FF", +"v. c #AAD5FF", +"b. c #A7D8FF", +"n. c #AED8FF", +"m. c #B7D9F5", +"M. c #B0D0FE", +"N. c #B4DAFF", +"B. c #BBDEFF", +"V. c #BDE0FF", +"C. c #C9C6C0", +"Z. c #CDCBC3", +"A. c #C3C5CB", +"S. c #CECCCB", +"D. c #D0CCC7", +"F. c #CACDD1", +"G. c #D2D6D7", +"H. c #DAD5D5", +"J. c #D2D5DF", +"K. c #DEDDDD", +"L. c #E2DEDB", +"P. c #E5E2DC", +"I. c #C6CFEE", +"U. c #C8D0E0", +"Y. c #C6DCEE", +"T. c #D8DDE3", +"R. c #C2D3F3", +"E. c #CCD4F0", +"W. c #C0DFFF", +"Q. c #D3DAF2", +"!. c #CDE3F5", +"~. c #C3E3FF", +"^. c #CAE6FF", +"/. c #CDE9FF", +"(. c #DCE2F5", +"). c #D1E7FF", +"_. c #D3EBFF", +"`. c #D9EDFF", +"'. c #D5F1FF", +"]. c #DBF1FF", +"[. c #E3E3E5", +"{. c #E2E4E8", +"}. c #E7E8ED", +"|. c #E1E6F6", +" X c #E1EDF7", +".X c #E3F3FF", +"XX c #EAF7FF", +"oX c #F2F2F1", +"OX c #F2F4FB", +"+X c #F6FBFF", +"@X c #FFFFFF", +"#X c None", +/* pixels */ +"#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X#X#X#X#X#X#X; ) ` v = @ #X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X#X#X#X* ] <.S.A.7.6.-.&.) + #X#X#X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X#X#X< Z.J.9.8.8.^ ~ W R *.&.= #X#X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X#X) P.i./ l.)..XXX.X).z.! T %.> #X#X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X< P.k.e.~.].`.`.`._._._.~.r.G $.* #X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X% D.R.r.V.~.~.^.^.^.^.~.W.B.V.y.F X.. #X#X#X#X#X#X#X#X#X#X", +"#X#X#X` }.t.c.N.N.B.~.~.~.B.B.N.N.v.b.( { : #X#X#X#X#X#X#X#X#X#X", +"#X#X#XC.R.y.c.v.n.N.N.N.N.N.N.n.v.c.g.f.T ' #X#X#X#X#X#X#X#X#X", +"#X#X= L.M.d.g.c.c.v.v.v.v.v.v.c.g.f.f.b.Q } o #X#X#X#X#X#X#X#X#X", +"#X#X1 [.x.g.g.f.g.g.h.c.c.g.g.f.f.g.c.N.q.{ $ #X#X#X#X#X#X#X#X#X", +"#X#X) {.v.n.c.g.g.f.f.f.f.f.f.g.h.v.N.~.s.{ & #X#X#X#X#X#X#X#X#X", +"#X#X1 [.N.B.N.n.v.c.c.h.h.c.c.v.n.N.B./.j.[ # #X#X#X#X#X#X#X#X#X", +"#X#X= H.~.~.~.V.B.N.N.N.N.N.N.B.V.~.^._.w._ o #X#X#X#X#X#X#X#X#X", +"#X#X% >.!.~./.^.~.~.~.~.~.~.~.^.^./._._.+.v #X#X#X#X#X#X#X#X#X", +"#X#X#X' T.B._._././././././././._._.].m.Y - #X#X#X#X#X#X#X#X#X#X", +"#X#X#X* >.!.~.`._._._._._._._._.`.].'.O.) X #X#X#X#X#X#X#X#X#X#X", +"#X#X#X#X..K. X.XXX.X`.`.`.`.`.`..X].4.` , #X#X#X#X#X#X#X#X#X#X#X", +"#X#X#X@X+X@X@X@X@X+XXX.X.X.X.X.X!.@.` &.a.O e #X#X#X#X#X#X#X#X#X", +"#X#X@X+X3.K Z S I Q.@X.X`.!.Y.p.o.` < .G.H.:.h #X#X#X#X#X#X#X#X", +"#X@X|.H C C C C C Z 2.@XF.=...` < @ #XO #.U.1.B g #X#X#X#X#X#X#X", +"@X@XJ C C C C C C C C k.oX| - % #X#X#X7 ;.,.n m B g #X#X#X#X#X#X", +"@X0.C C C C C C C C C D @XK.#X#X#X#X#X#Xs z k x m B f #X#X#X#X#X", +"@XI C C C C C C C C C C (.@X#X#X#X#X#X#X#Xr a l x M V d #X#X#X#X", +"@XP C C C C C C C C C C E.@X#X#X#X#X#X#X#X#Xt a l x M B u #X#X#X", +"@XE C C C C C C C C C Z OX@X#X#X#X#X#X#X#X#X#X0 a l x m V y 5 #X", +"@XQ.Z C C C C C C C C U @X#X#X#X#X#X#X#X#X#X#X#X0 a l x N b w #X", +"#X@X3.C C C C C C C D OX@X#X#X#X#X#X#X#X#X#X#X#X#X9 a l c j 6 #X", +"#X#X@X5.A C C C C L |.@X#X#X#X#X#X#X#X#X#X#X#X#X#X#Xq p i 3 #X#X", +"#X#X#X@X+XI.0.u.(.@X@X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X2 8 4 #X#X#X", +"#X#X#X#X@X@X@X@X@X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X#X" +}; diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp new file mode 100644 index 0000000000..0818975928 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.cpp @@ -0,0 +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 "org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h" + +// Blueberry +#include +#include +#include + +// Qmitk +#include "QmitkMatchPointBrowser.h" + +// Qt +#include +#include +#include +#include + +//MITK +#include +#include "MatchPointBrowserConstants.h" +#include "mitkAlgorithmInfoSelectionProvider.h" + +// MatchPoint +#include +#include +#include +#include +#include + +const std::string QmitkMatchPointBrowser::VIEW_ID = "org.mitk.views.matchpoint.algorithm.browser"; + +QmitkMatchPointBrowser::QmitkMatchPointBrowser() + : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL) +{ +} + +QmitkMatchPointBrowser::~QmitkMatchPointBrowser() +{ +} + +void QmitkMatchPointBrowser::OnPreferencesChanged(const berry::IBerryPreferences* /*prefs*/) +{ + this->OnSearchFolderButtonPushed(); +} + +void QmitkMatchPointBrowser::CreateConnections() +{ + connect(m_Controls.m_pbSearchFolder, SIGNAL(clicked()), this, SLOT(OnSearchFolderButtonPushed())); + connect(m_Controls.m_algoTreeView, SIGNAL(clicked(const QModelIndex&)), this, + SLOT(OnAlgoListSelectionChanged(const QModelIndex&))); + connect(m_Controls.pbClearSearch, SIGNAL(clicked()), m_Controls.lineSearch, SLOT(clear())); + connect(m_Controls.lineSearch, SIGNAL(textChanged(const QString&)), this, + SLOT(OnSearchChanged(const QString&))); +} + +void QmitkMatchPointBrowser::OnSearchFolderButtonPushed() +{ + RetrieveAndStorePreferenceValues(); + // test if some folder list non-empty + int folderCount = m_currentSearchPaths.count(); + + if (!folderCount) + { + Error(QString("No search folder selected for MatchPoint algorithm browser! Please set search paths in the MatchPoint preference page.")); + m_DLLInfoList.clear(); + } + else + { + map::deployment::DLLDirectoryBrowser::Pointer browser = map::deployment::DLLDirectoryBrowser::New(); + + foreach(QString path, m_currentSearchPaths) + { + browser->addDLLSearchLocation(path.toStdString()); + } + + browser->update(); + m_DLLInfoList = browser->getLibraryInfos(); + } + + m_Controls.groupWarning->setVisible(m_DLLInfoList.empty()); + m_Controls.groupList->setVisible(!m_DLLInfoList.empty()); + + m_algModel->SetAlgorithms(m_DLLInfoList); + m_Controls.lineSearch->clear(); +} + +void QmitkMatchPointBrowser::OnAlgoListSelectionChanged(const QModelIndex& index) +{ + QVariant vIndex = index.data(Qt::UserRole).toInt(); + map::deployment::DLLInfo::ConstPointer currentItemInfo = NULL; + + if (vIndex.isValid()) + { + int algListIndex = vIndex.toInt(); + + if (algListIndex < m_DLLInfoList.size()) + { + currentItemInfo = m_DLLInfoList[algListIndex]; + } + } + + m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); + + if (currentItemInfo) + { + //update selection provider + mitk::MAPAlgorithmInfoSelection::Pointer infoSelection = mitk::MAPAlgorithmInfoSelection::Pointer( + new mitk::MAPAlgorithmInfoSelection(currentItemInfo)); + this->m_SelectionProvider->SetInfoSelection(infoSelection); + } +} + + +void QmitkMatchPointBrowser::OnSearchChanged(const QString& text) +{ + m_filterProxy->setFilterRegExp(text); + m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); +}; + +void QmitkMatchPointBrowser::CreateQtPartControl(QWidget* parent) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + m_Parent = parent; + + m_algModel = new QmitkAlgorithmListModel(parent); + m_filterProxy = new QSortFilterProxyModel(parent); + + //! [Qt Selection Provider registration] + // create new qt selection provider + m_SelectionProvider = new mitk::AlgorithmInfoSelectionProvider(); + + m_filterProxy->setSourceModel(m_algModel); + m_filterProxy->setDynamicSortFilter(true); + m_filterProxy->setFilterKeyColumn(-1); + m_Controls.m_algoTreeView->setModel(m_filterProxy); + m_Controls.m_algoTreeView->setSelectionMode(QAbstractItemView::SingleSelection); + + m_Controls.m_algoTreeView->header()->setStretchLastSection(false); + m_Controls.m_algoTreeView->header()->setSectionResizeMode(0, QHeaderView::Stretch); + m_Controls.m_algoTreeView->setColumnHidden(3, true); + + this->CreateConnections(); +} + +void QmitkMatchPointBrowser::SetSelectionProvider() +{ + this->GetSite()->SetSelectionProvider(m_SelectionProvider); +} + +void QmitkMatchPointBrowser::SetFocus() +{ +} + +void QmitkMatchPointBrowser::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); +} + +void QmitkMatchPointBrowser::RetrieveAndStorePreferenceValues() +{ + berry::IBerryPreferences::Pointer prefs = this->RetrievePreferences(); + + bool loadApplicationDir = prefs->GetBool( + MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), true); + bool loadHomeDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), false); + bool loadCurrentDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), + false); + bool loadAutoLoadDir = prefs->GetBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), + false); + + // Get some default application paths. + QStringList newPaths; + + // Here we can use the preferences to set up the builder, + if (loadApplicationDir) + { + newPaths << QCoreApplication::applicationDirPath(); + } + + if (loadHomeDir) + { + newPaths << QDir::homePath(); + } + + if (loadCurrentDir) + { + newPaths << QDir::currentPath(); + } + + if (loadAutoLoadDir) + { + char* deployedAlgorithmLoadPath = getenv("MAP_MDRA_LOAD_PATH"); + + if (deployedAlgorithmLoadPath != NULL) + { + // The load path may in fact be a semi-colon or colon separated list of directories, not just one. + QString paths(deployedAlgorithmLoadPath); + +#ifdef Q_OS_WIN32 + QString pathSeparator(";"); +#else + QString pathSeparator(":"); +#endif + + QStringList splitPath = paths.split(pathSeparator, QString::SkipEmptyParts); + + foreach(QString path, splitPath) + { + QDir dir = QDir(path); + newPaths << dir.absolutePath(); + } + } + + } + + // We get additional directory paths from preferences. + QString pathString = prefs->Get(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), + tr("")); + QStringList additionalPaths = pathString.split(";", QString::SkipEmptyParts); + newPaths << additionalPaths; + + QString additionalAlgorirthmsString = prefs->Get( + MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), tr("")); + additionalPaths = additionalAlgorirthmsString.split(";", QString::SkipEmptyParts); + newPaths << additionalPaths; + + m_currentSearchPaths = newPaths; +} + +berry::IBerryPreferences::Pointer QmitkMatchPointBrowser::RetrievePreferences() +{ + berry::IPreferencesService* prefService + = berry::Platform::GetPreferencesService(); + + assert(prefService); + + QString id = tr("/") + QString::fromStdString(MatchPointBrowserConstants::VIEW_ID); + berry::IBerryPreferences::Pointer prefs + = (prefService->GetSystemPreferences()->Node(id)) + .Cast(); + + assert(prefs); + + return prefs; +} + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.h new file mode 100644 index 0000000000..974226a3c9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowser.h @@ -0,0 +1,127 @@ +/*=================================================================== + +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 __Q_MITK_MATCHPOINT_H +#define __Q_MITK_MATCHPOINT_H + +#include + +#include +#include +#include +#include + +//QT +#include + +// MatchPoint +#include +#include +#include + +#include "ui_QmitkMatchPointBrowserControls.h" +#include "QmitkMAPAlgorithmModel.h" +#include "QmitkAlgorithmListModel.h" +#include "mitkAlgorithmInfoSelectionProvider.h" + +/*! +\brief MatchPoint + +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + +\sa QmitkFunctionality +\ingroup ${plugin_target}_internal +*/ +class QmitkMatchPointBrowser : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPointBrowser) + + QmitkMatchPointBrowser(); + virtual ~QmitkMatchPointBrowser(); + + /** + * \brief Called by the framework to indicate that the preferences have changed. + * \param prefs not used, as we call RetrievePreferenceValues(). + */ + void OnPreferencesChanged(const berry::IBerryPreferences* prefs); + + protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + /// \brief Called when the user clicks the GUI button + + void OnSearchFolderButtonPushed(); + + void OnAlgoListSelectionChanged(const QModelIndex&); + + void OnSearchChanged(const QString&); + +protected: + virtual void CreateQtPartControl(QWidget* parent); + virtual void SetFocus(); + + Ui::MatchPointBrowserControls m_Controls; + + //! [Qt Selection Provider] + /** @brief this pointer holds the selection provider*/ + mitk::AlgorithmInfoSelectionProvider::Pointer m_SelectionProvider; + //! [Qt Selection Provider] + +private: + void SetSelectionProvider(); + + void Error(QString msg); + + /** + * \brief Called on startup and by OnPreferencesChanged to load all + * preferences except the temporary folder into member variables. + */ + void RetrieveAndStorePreferenceValues(); + + /** + * \brief Called to get hold of the actual preferences node. + */ + berry::IBerryPreferences::Pointer RetrievePreferences(); + + QWidget* m_Parent; + + ::map::deployment::DLLDirectoryBrowser::DLLInfoListType m_DLLInfoList; + + QStringList m_currentSearchPaths; + QmitkAlgorithmListModel* m_algModel; + QSortFilterProxyModel* m_filterProxy; + + ::map::deployment::DLLHandle::Pointer m_LoadedDLLHandle; + ::map::algorithm::RegistrationAlgorithmBase::Pointer m_LoadedAlgorithm; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowserControls.ui b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowserControls.ui new file mode 100644 index 0000000000..d1cac4c797 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/QmitkMatchPointBrowserControls.ui @@ -0,0 +1,206 @@ + + + MatchPointBrowserControls + + + + 0 + 0 + 452 + 812 + + + + + 5 + + + 5 + + + + + + + Available registration algorithms: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Rescan all search directories for deployed MatchPoint algorithms. + + + Rescan + + + + + + + + + + 0 + + + + + + 50 + false + + + + <html><head/><body><p align="center"><span style=" font-weight:600; color:#ff0000;">Warning!</span></p><p><span style=" color:#ff0000;">Unable to detect any algorithms. Please check in the &quot;MatchPoint&quot; preferences (CTRL+P), if search directories are set (correctly).</span></p></body></html> + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 0 + + + + + 0 + + + + + Type in name (parts) or keywords to search for certain algorithms. + + + Search for specific algorithms... + + + + + + + + 25 + 24 + + + + Clear the current search and show all algorithms. + + + X + + + + + + + + + QAbstractItemView::AllEditTriggers + + + false + + + true + + + true + + + true + + + 60 + + + + + + + true + + + false + + + Selected algorithm information: + + + true + + + 0 + + + + + + + + + + + + + + QmitkAlgorithmProfileViewer + QWidget +
QmitkAlgorithmProfileViewer.h
+
+
+ + + + + 5 + + + 5 + + + true + + + true + + + true + + +
diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.cpp new file mode 100644 index 0000000000..d7d660fc6b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.cpp @@ -0,0 +1,64 @@ +/*=================================================================== + +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 "mitkAlgorithmInfoSelectionProvider.h" +#include "mitkMAPAlgorithmInfoSelection.h" + +namespace mitk { + +AlgorithmInfoSelectionProvider::AlgorithmInfoSelectionProvider() : _selection(NULL) +{ + +} + +void AlgorithmInfoSelectionProvider::AddSelectionChangedListener( berry::ISelectionChangedListener* listener ) +{ + _selectionEvents.AddListener(listener); +} + +void AlgorithmInfoSelectionProvider::RemoveSelectionChangedListener( berry::ISelectionChangedListener* listener ) +{ + _selectionEvents.RemoveListener(listener); +} + +berry::ISelection::ConstPointer AlgorithmInfoSelectionProvider::GetSelection() const +{ + return _selection; +} + +void AlgorithmInfoSelectionProvider::SetSelection(const berry::ISelection::ConstPointer& selection) +{ + _selection = selection.Cast(); +} + +MAPAlgorithmInfoSelection::ConstPointer AlgorithmInfoSelectionProvider::GetInfoSelection() const +{ + return _selection; +} + +void AlgorithmInfoSelectionProvider::SetInfoSelection(MAPAlgorithmInfoSelection::ConstPointer selection) +{ + if (_selection != selection) + { + _selection = selection; + berry::SelectionChangedEvent::Pointer event(new berry::SelectionChangedEvent(berry::ISelectionProvider::Pointer(this), selection)); + _selectionEvents.selectionChanged(event); + } +} + + + +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.h new file mode 100644 index 0000000000..08e09ac433 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/mitkAlgorithmInfoSelectionProvider.h @@ -0,0 +1,59 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_ALGORITHM_SELECTION_PROVIDER_H +#define _MITK_ALGORITHM_SELECTION_PROVIDER_H + +#include + +#include + +#include + +#include "mitkMAPAlgorithmInfoSelection.h" + +namespace mitk +{ + +class AlgorithmInfoSelectionProvider: public QObject, + public berry::ISelectionProvider +{ + Q_OBJECT + +public: + + berryObjectMacro(AlgorithmInfoSelectionProvider) + + AlgorithmInfoSelectionProvider(); + + void AddSelectionChangedListener(berry::ISelectionChangedListener* listener); + + void RemoveSelectionChangedListener( berry::ISelectionChangedListener* listener); + + berry::ISelection::ConstPointer GetSelection() const; + void SetSelection(const berry::ISelection::ConstPointer& selection); + + MAPAlgorithmInfoSelection::ConstPointer GetInfoSelection() const; + void SetInfoSelection(MAPAlgorithmInfoSelection::ConstPointer selection); + +protected: + berry::ISelectionChangedListener::Events _selectionEvents; + MAPAlgorithmInfoSelection::ConstPointer _selection; +}; + +} + +#endif /* BERRYQTSELECTIONPROVIDER_H_ */ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.cpp new file mode 100644 index 0000000000..16c8aea7bf --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.cpp @@ -0,0 +1,40 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h" + +#include "QmitkMatchPointBrowser.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithm_browser_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_algorithm_browser_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPointBrowser, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_algorithm_browser_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithm_browser_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h new file mode 100644 index 0000000000..322c2dc610 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.browser/src/internal/org_mitk_gui_qt_matchpoint_algorithm_browser_Activator.h @@ -0,0 +1,42 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef org_mitk_gui_qt_matchpoint_algorithm_browser_Activator_h +#define org_mitk_gui_qt_matchpoint_algorithm_browser_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_algorithm_browser_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_algorithm_browser") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_algorithmcontrol_Activator + +#endif // org_mitk_gui_qt_algorithmcontrol_Activator_h diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/CMakeLists.txt new file mode 100644 index 0000000000..d1788ddd39 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_matchpoint_algorithm_control) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_MITK_GUI_QT_ALG_CTRL_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration MitkMatchPointRegistrationUI + PACKAGE_DEPENDS CTK|CTKCore +) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..a0fdd36bd9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/Manual.dox @@ -0,0 +1,51 @@ +/** +\page org_mitk_gui_qt_matchpoint_algorithm_control The MatchPoint Algorithm Control Plugin + +\imageMacro{map-icon-run.png, "Icon of the MatchPoint Algorithm Control", 3} + +\li \ref MAP_RUN_Introduction +\li \ref MAP_RUN_Contact +\li \ref MAP_RUN_Usage + +\section MAP_RUN_Introduction Introduction +This plugin offers the user a way to use a selected registration algorithm in order to determine a registration for two selected images. +For the selection of an algorithm please see MatchPoint Algorithm Browser (\ref org_mitk_gui_qt_algorithm_browser). + +\section MAP_RUN_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_RUN_Usage Usage +\imageMacro{control_example.png, "Example screenshot showing the control plugin in use.", 14} +To use the plugin a registration algorithm must be loaded and the moving as well as the target image must be selected.\n +The moving image will be the image whicht will be registered onto the target image. Thus the result would show a mapped input image +in the geometry (field of view, orientation, spacing) defined by the target image.\n +The images will be selected in the data manager using multi select (press the CTRL-key while selecting the nodes in the data manager). +The first selection is the moving image, the second is the target image.\n +If an algorithm is loaded and input images are selected, the plugin will automatically switch to the "Execution" tab. + +\subsection MAP_RUN_Usage_selection Selection tab +\imageMacro{step1_selection.png, "Details of the selection tab.", 8} +In this tab you can load/"book" the algorithm selected in the MatchPoint Algorithm Browser. In the tab you see the ID of the algorithm +selected by the browser and its profile information.\n +If you press "Load selected algorithm", the algorithm will be used by the controller plugin in and the name of the algorithm occurs +in the text field "Loaded algorithm" (at the top of the plugin view).\n +At this point, it has no effect if you change the the selection in the browser. The controller plugin will keep the loaded algorithm until +you choose to load another one. + +\subsection MAP_RUN_Usage_exec Execution tab +\imageMacro{step2_execution.png, "Details of the execution tab.",8} +In this tab you can specify a name for the registration job (this will determine the names of the result nodes in the data manager).\n +You can also choose to "store registration" (which is normally the goal of the whole process, because this is the very result of the algorithm ;).\n +Additionally you can "Generate + store mapped result". This is a convenience feature which often saves you the time to use the mapper plugin afterwards. +It will do the same like using the mapper plugin with the moving and target image, setting padding value "0" and using "linear interpolation". +If you need other settings, skip the convenience generation and use the mapper plugin directly.\n +"Start" will trigger the registration process. Some algorithms allow to be stopped while registering. In those cases, there is an "Stop" button enabled, +as soon as the registration process starts. + +\subsection MAP_RUN_Usage_settings Settings tab +\imageMacro{step3_settings.png, "Details of the settings tab.",8} +In this tab, you can parametrize the loaded algorithm (befor it starts), if it offers any possibility to do so. +*/ + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/control_example.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/control_example.png new file mode 100644 index 0000000000..ce47acf90b Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/control_example.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/map-icon-run.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/map-icon-run.png new file mode 100644 index 0000000000..7606e0e4d8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/map-icon-run.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step1_selection.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step1_selection.png new file mode 100644 index 0000000000..31521809be Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step1_selection.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step2_execution.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step2_execution.png new file mode 100644 index 0000000000..2dceb5b88c Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step2_execution.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step3_settings.PNG b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step3_settings.PNG new file mode 100644 index 0000000000..9aed9ef877 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/UserManual/step3_settings.PNG differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..06eb4aca0c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk org.mitk + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_internal Internal + \ingroup org_mitk + + \brief This subcategory includes the internal classes of the org.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/files.cmake new file mode 100644 index 0000000000..aff465200d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/files.cmake @@ -0,0 +1,43 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.cpp + QmitkMatchPoint.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h + src/internal/QmitkMatchPoint.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/manifest_headers.cmake new file mode 100644 index 0000000000..9ec53149c4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Algorithm Control") +set(Plugin-Version "0.2") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager org.mitk.matchpoint.core.helper) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/plugin.xml new file mode 100644 index 0000000000..f0c8d9c5d4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/resources/icon.png b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/resources/icon.png new file mode 100644 index 0000000000..7606e0e4d8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp new file mode 100644 index 0000000000..4e1deb18ab --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp @@ -0,0 +1,980 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h" + +// Blueberry +#include +#include +#include +#include + +// Mitk +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qmitk +#include "QmitkMatchPoint.h" +#include +#include + +// Qt +#include +#include +#include +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const std::string QmitkMatchPoint::VIEW_ID = "org.mitk.views.matchpoint.algorithm.control"; + +QmitkMatchPoint::QmitkMatchPoint() + : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL) +{ + m_CanLoadAlgorithm = false; + m_ValidInputs = false; + m_Working = false; + m_spSelectedTargetData = NULL; + m_spSelectedMovingData = NULL; + m_spSelectedTargetMaskData = NULL; + m_spSelectedMovingMaskData = NULL; +} + +QmitkMatchPoint::~QmitkMatchPoint() +{ + // remove selection service + berry::ISelectionService* s = this->GetSite()->GetWorkbenchWindow()->GetSelectionService(); + + if (s) + { + s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); + } +} + +void QmitkMatchPoint::SetFocus() +{ +} + +void QmitkMatchPoint::CreateConnections() +{ + + connect(m_Controls.checkMovingMask, SIGNAL(toggled(bool)), this, + SLOT(OnMaskCheckBoxToggeled(bool))); + connect(m_Controls.checkTargetMask, SIGNAL(toggled(bool)), this, + SLOT(OnMaskCheckBoxToggeled(bool))); + + // ------ + // Tab 1 - Shared library loading interface + // ------ + + connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); + + // ----- + // Tab 2 - Execution + // ----- + connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); + connect(m_Controls.m_pbStopReg, SIGNAL(clicked()), this, SLOT(OnStopRegBtnPushed())); + connect(m_Controls.m_pbSaveLog, SIGNAL(clicked()), this, SLOT(OnSaveLogBtnPushed())); +} + +const map::deployment::DLLInfo* QmitkMatchPoint::GetSelectedAlgorithmDLL() const +{ + return m_SelectedAlgorithmInfo; +} + +void QmitkMatchPoint::OnMaskCheckBoxToggeled(bool checked) +{ + if (!m_Working) + { + CheckInputs(); + ConfigureRegistrationControls(); + } +}; + +void QmitkMatchPoint::OnSelectedAlgorithmChanged() +{ + std::stringstream descriptionString; + + ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); + + if (!currentItemInfo) + { + Error(QString("No valid algorithm is selected. ABORTING.")); + return; + } + + m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); + + m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( + currentItemInfo->getAlgorithmUID().getName())); + + // enable loading + m_CanLoadAlgorithm = true; + this->AdaptFolderGUIElements(); +} + +void QmitkMatchPoint::OnLoadAlgorithmButtonPushed() +{ + map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); + + if (!dllInfo) + { + Error(QString("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); + return; + } + + ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( + dllInfo->getLibraryFilePath()); + ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm + = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); + + if (tempAlgorithm.IsNull()) + { + Error(QString("Error. Cannot load selected algorithm.")); + return; + } + + this->m_LoadedAlgorithm = tempAlgorithm; + this->m_LoadedDLLHandle = tempDLLHandle; + + this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); + m_Controls.checkMovingMask->setChecked(false); + m_Controls.checkTargetMask->setChecked(false); + + this->AdaptFolderGUIElements(); + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); + this->m_Controls.m_tabs->setCurrentIndex(1); +} + +void QmitkMatchPoint::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); + + m_Controls.m_teLog->append(QString("") + msg + QString("")); +} + +void QmitkMatchPoint::AdaptFolderGUIElements() +{ + m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); +} + +void QmitkMatchPoint::CreateQtPartControl(QWidget* parent) +{ + + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + m_Parent = parent; + + m_Controls.checkMovingMask->setChecked(false); + m_Controls.checkTargetMask->setChecked(false); + m_Controls.m_tabs->setCurrentIndex(0); + + m_AlgorithmSelectionListener.reset(new berry::SelectionChangedAdapter(this, + &QmitkMatchPoint::OnAlgorithmSelectionChanged)); + + // register selection listener + GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( + m_AlgorithmSelectionListener.data()); + + this->CreateConnections(); + this->AdaptFolderGUIElements(); + this->CheckInputs(); + this->ConfigureProgressInfos(); + this->ConfigureRegistrationControls(); + + berry::ISelection::ConstPointer selection = + GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); + + this->UpdateAlgorithmSelection(selection); +} + +bool QmitkMatchPoint::CheckInputs() +{ + bool validMoving = false; + bool validTarget = false; + + bool validMovingMask = false; + bool validTargetMask = false; + + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + + if (m_LoadedAlgorithm.IsNull()) + { + m_Controls.m_lbMovingName->setText(QString("No algorithm seleted!")); + m_spSelectedMovingNode = NULL; + m_spSelectedMovingData = NULL; + m_Controls.m_lbTargetName->setText(QString("No algorithm seleted!")); + m_spSelectedTargetNode = NULL; + m_spSelectedTargetData = NULL; + + m_spSelectedMovingMaskNode = NULL; + m_spSelectedMovingMaskData = NULL; + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + else + { + QList nodes = this->GetDataManagerSelection(); + + mitk::Image* movingImage = NULL; + mitk::PointSet* movingPointSet = NULL; + mitk::Image* targetImage = NULL; + mitk::PointSet* targetPointSet = NULL; + + mitk::Image* movingMaskImage = NULL; + mitk::Image* targetMaskImage = NULL; + + typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; + typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface + PointSetRegInterface; + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; + + PointSetRegInterface* pPointSetInterface = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + MaskRegInterface* pMaskInterface = dynamic_cast(m_LoadedAlgorithm.GetPointer()); + + if (nodes.count() < 1) + { + m_Controls.m_lbMovingName->setText(QString("no data selected!")); + m_spSelectedMovingNode = NULL; + m_spSelectedMovingData = NULL; + } + else + { + m_spSelectedMovingNode = nodes.front(); + m_spSelectedMovingData = m_spSelectedMovingNode->GetData(); + movingImage = dynamic_cast(m_spSelectedMovingNode->GetData()); + movingPointSet = dynamic_cast(m_spSelectedMovingNode->GetData()); + + if (movingPointSet && pPointSetInterface) + { + validMoving = true; + } + else if (movingImage && !pPointSetInterface) + { + if (movingImage->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() + && movingImage->GetTimeSteps() > 1) + { + //images has multiple time steps and a time step has the correct dimensionality + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(movingImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + m_spSelectedMovingData = imageTimeSelector->GetOutput(); + validMoving = true; + m_Controls.m_teLog->append( + QString("Selected moving image has multiple time steps. First time step is used as moving image.")); + } + else if (movingImage->GetDimension() != m_LoadedAlgorithm->getMovingDimensions()) + { + m_Controls.m_lbMovingName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getMovingDimensions()) + QString("D needed")); + } + else + { + validMoving = true; + } + } + else + { + m_Controls.m_lbMovingName->setText(QString("no supported data selected!")); + } + + nodes.removeFirst(); + } + + if (nodes.count() < 1) + { + m_Controls.m_lbTargetName->setText(QString("no data selected!")); + m_spSelectedTargetNode = NULL; + m_spSelectedTargetData = NULL; + } + else + { + m_spSelectedTargetNode = nodes.front(); + m_spSelectedTargetData = m_spSelectedTargetNode->GetData(); + targetImage = dynamic_cast(m_spSelectedTargetNode->GetData()); + targetPointSet = dynamic_cast(m_spSelectedTargetNode->GetData()); + + if (targetPointSet && pPointSetInterface) + { + validTarget = true; + } + else if (targetImage && !pPointSetInterface) + { + if (targetImage->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() + && targetImage->GetTimeSteps() > 1) + { + //images has multiple time steps and a time step has the correct dimensionality + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(targetImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + m_spSelectedTargetData = imageTimeSelector->GetOutput(); + validTarget = true; + m_Controls.m_teLog->append( + QString("Selected target image has multiple time steps. First time step is used as target image.")); + } + else if (targetImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions()) + { + m_Controls.m_lbTargetName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D needed")); + } + else + { + validTarget = true; + } + } + else + { + m_Controls.m_lbTargetName->setText(QString("no supported data selected!")); + } + + nodes.removeFirst(); + } + + if (m_Controls.checkMovingMask->isChecked()) + { + if (nodes.count() < 1) + { + m_Controls.m_lbMovingMaskName->setText(QString("no data selected!")); + m_spSelectedMovingMaskNode = NULL; + m_spSelectedMovingMaskData = NULL; + } + else + { + m_spSelectedMovingMaskNode = nodes.front(); + m_spSelectedMovingMaskData = NULL; + + movingMaskImage = dynamic_cast(m_spSelectedMovingMaskNode->GetData()); + + bool isMask = maskPredicate->CheckNode(m_spSelectedMovingMaskNode); + + if (!isMask) + { + m_Controls.m_lbMovingMaskName->setText(QString("no mask selected!")); + } + else if (movingMaskImage && pMaskInterface) + { + if (movingMaskImage->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() + && movingMaskImage->GetTimeSteps() > 1) + { + //images has multiple time steps and a time step has the correct dimensionality + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(movingMaskImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + m_spSelectedMovingMaskData = imageTimeSelector->GetOutput(); + validMovingMask = true; + m_Controls.m_teLog->append( + QString("Selected moving mask has multiple time steps. First time step is used as moving mask.")); + } + else if (movingMaskImage->GetDimension() != m_LoadedAlgorithm->getMovingDimensions()) + { + m_Controls.m_lbMovingMaskName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getMovingDimensions()) + QString("D needed")); + } + else + { + m_spSelectedMovingMaskData = movingMaskImage; + validMovingMask = true; + } + } + else + { + m_Controls.m_lbMovingMaskName->setText( + QString("no supported data selected!")); + } + + nodes.removeFirst(); + } + } + else + { + m_Controls.m_lbMovingMaskName->setText(QString("mask deactivated")); + validMovingMask = true; + m_spSelectedMovingMaskNode = NULL; + m_spSelectedMovingMaskData = NULL; + } + + if (m_Controls.checkTargetMask->isChecked()) + { + if (nodes.count() < 1) + { + m_Controls.m_lbTargetMaskName->setText(QString("no data selected!")); + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + else + { + m_spSelectedTargetMaskNode = nodes.front(); + m_spSelectedTargetMaskData = NULL; + targetMaskImage = dynamic_cast(m_spSelectedTargetMaskNode->GetData()); + + bool isMask = maskPredicate->CheckNode(m_spSelectedTargetMaskNode); + + if (!isMask) + { + m_Controls.m_lbTargetMaskName->setText(QString("no mask selected!")); + } + else if (targetMaskImage && pMaskInterface) + { + if (targetMaskImage->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() + && targetMaskImage->GetTimeSteps() > 1) + { + //images has multiple time steps and a time step has the correct dimensionality + mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); + imageTimeSelector->SetInput(targetMaskImage); + imageTimeSelector->SetTimeNr(0); + imageTimeSelector->UpdateLargestPossibleRegion(); + + m_spSelectedTargetMaskData = imageTimeSelector->GetOutput(); + validTargetMask = true; + m_Controls.m_teLog->append( + QString("Selected target mask has multiple time steps. First time step is used as target mask.")); + } + else if (targetMaskImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions()) + { + m_Controls.m_lbTargetMaskName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D needed")); + } + else + { + m_spSelectedTargetMaskData = targetMaskImage; + validTargetMask = true; + } + } + else + { + m_Controls.m_lbTargetMaskName->setText( + QString("no supported data selected!")); + } + } + + } + else + { + m_Controls.m_lbTargetMaskName->setText(QString("mask deactivated")); + validTargetMask = true; + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + + } + + if (validMoving) + { + m_Controls.m_lbMovingName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedMovingNode))); + } + + if (validTarget) + { + m_Controls.m_lbTargetName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedTargetNode))); + } + + if (validMovingMask && m_Controls.checkMovingMask->isChecked()) + { + m_Controls.m_lbMovingMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedMovingMaskNode))); + } + + if (validTargetMask && m_Controls.checkTargetMask->isChecked()) + { + m_Controls.m_lbTargetMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedTargetMaskNode))); + } + + m_ValidInputs = validMoving && validTarget && validMovingMask && validTargetMask; + return m_ValidInputs; +} + +std::string QmitkMatchPoint::GetInputNodeDisplayName(const mitk::DataNode* node) const +{ + std::string result = "UNDEFINED/NULL"; + + if (node) + { + result = node->GetName(); + + const mitk::PointSet* pointSet = dynamic_cast(node->GetData()); + + if (pointSet) + { + mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(node); + + if (sources.IsNotNull() && sources->Size() > 0) + { + result = result + " (" + sources->GetElement(0)->GetName() + ")"; + } + + } + } + + return result; +} + +mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPoint::GetRegNodes() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); + mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); + + for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); + ++pos) + { + if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + result->push_back(*pos); + } + } + + return result; +} + +std::string QmitkMatchPoint::GetDefaultRegJobName() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); + mitk::DataStorage::SetOfObjects::ElementIdentifier estimatedIndex = nodes->Size(); + + bool isUnique = false; + std::string result = "Unnamed Reg"; + + while (!isUnique) + { + ++estimatedIndex; + result = "Reg #" +::map::core::convert::toStr(estimatedIndex); + isUnique = this->GetDataStorage()->GetNamedNode(result) == NULL; + } + + return result; +} + +void QmitkMatchPoint::ConfigureRegistrationControls() +{ + m_Controls.m_tabSelection->setEnabled(!m_Working); + m_Controls.m_leRegJobName->setEnabled(!m_Working); + m_Controls.groupMasks->setEnabled(!m_Working); + + m_Controls.m_pbStartReg->setEnabled(false); + m_Controls.m_pbStopReg->setEnabled(false); + m_Controls.m_pbStopReg->setVisible(false); + + m_Controls.m_lbMovingMaskName->setVisible(m_Controls.checkMovingMask->isChecked()); + m_Controls.m_lbTargetMaskName->setVisible(m_Controls.checkTargetMask->isChecked()); + + if (m_LoadedAlgorithm.IsNotNull()) + { + m_Controls.m_tabSettings->setEnabled(!m_Working); + m_Controls.m_tabExecution->setEnabled(true); + m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); + m_Controls.m_leRegJobName->setEnabled(!m_Working); + m_Controls.m_checkMapEntity->setEnabled(!m_Working); + m_Controls.m_checkStoreReg->setEnabled(!m_Working); + + const IStoppableAlgorithm* pIterativ = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + if (pIterativ) + { + m_Controls.m_pbStopReg->setVisible(pIterativ->isStoppable()); + } + + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; + const MaskRegInterface* pMaskReg = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + m_Controls.groupMasks->setVisible(pMaskReg != NULL); + + //if the stop button is set to visible and the algorithm is working -> + //then the algorithm is stoppable, thus enable the button. + m_Controls.m_pbStopReg->setEnabled(m_Controls.m_pbStopReg->isVisible() && m_Working); + + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); + } + else + { + m_Controls.m_tabSettings->setEnabled(false); + m_Controls.m_tabExecution->setEnabled(false); + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString("no algorithm loaded!")); + m_Controls.groupMasks->setVisible(false); + } + + if (!m_Working) + { + this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultRegJobName())); + } +} + +void QmitkMatchPoint::ConfigureProgressInfos() +{ + const IIterativeAlgorithm* pIterative = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + const IMultiResAlgorithm* pMultiRes = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + m_Controls.m_progBarIteration->setVisible(pIterative); + m_Controls.m_lbProgBarIteration->setVisible(pIterative); + + + if (pIterative) + { + QString format = "%p% (%v/%m)"; + + if (!pIterative->hasMaxIterationCount()) + { + format = "%v"; + m_Controls.m_progBarIteration->setMaximum(0); + } + else + { + m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); + } + + m_Controls.m_progBarIteration->setFormat(format); + } + + if (pMultiRes) + { + m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); + + } + else + { + m_Controls.m_progBarLevel->setMaximum(1); + } + + m_Controls.m_progBarIteration->reset(); + m_Controls.m_progBarLevel->reset(); +} + +void QmitkMatchPoint::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes) +{ + if (!m_Working) + { + CheckInputs(); + ConfigureRegistrationControls(); + } +} + +void QmitkMatchPoint::OnStartRegBtnPushed() +{ + this->m_Working = true; + + //////////////////////////////// + //configure GUI + this->ConfigureProgressInfos(); + + m_Controls.m_progBarIteration->reset(); + m_Controls.m_progBarLevel->reset(); + + this->ConfigureRegistrationControls(); + + if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) + { + this->m_Controls.m_teLog->clear(); + } + + + ///////////////////////// + //create job and put it into the thread pool + QmitkRegistrationJob* pJob = new QmitkRegistrationJob(m_LoadedAlgorithm); + pJob->setAutoDelete(true); + + pJob->m_spTargetData = m_spSelectedTargetData; + pJob->m_spMovingData = m_spSelectedMovingData; + pJob->m_TargetNodeUID = mitk::EnsureUID(this->m_spSelectedTargetNode); + pJob->m_MovingNodeUID = mitk::EnsureUID(this->m_spSelectedMovingNode); + + if (m_spSelectedTargetMaskData.IsNotNull()) + { + pJob->m_spTargetMask = m_spSelectedTargetMaskData; + pJob->m_TargetMaskNodeUID = mitk::EnsureUID(this->m_spSelectedTargetMaskNode); + } + + if (m_spSelectedMovingMaskData.IsNotNull()) + { + pJob->m_spMovingMask = m_spSelectedMovingMaskData; + pJob->m_MovingMaskNodeUID = mitk::EnsureUID(this->m_spSelectedMovingMaskNode); + } + + pJob->m_JobName = m_Controls.m_leRegJobName->text().toStdString(); + + pJob->m_StoreReg = m_Controls.m_checkStoreReg->checkState() == Qt::Checked; + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); + connect(pJob, SIGNAL(RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, + const QmitkRegistrationJob*)), this, + SLOT(OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), + Qt::BlockingQueuedConnection); + connect(pJob, SIGNAL(MapResultNodeIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); + connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, + SLOT(OnAlgorithmStatusChanged(QString))); + connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, + SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); + connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, + bool, unsigned long))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + +void QmitkMatchPoint::OnStopRegBtnPushed() +{ + if (m_LoadedAlgorithm.IsNotNull()) + { + IStoppableAlgorithm* pIterativ = dynamic_cast(m_LoadedAlgorithm.GetPointer()); + + if (pIterativ && pIterativ->isStoppable()) + { + if (pIterativ->stopAlgorithm()) + { + + } + else + { + + } + + m_Controls.m_pbStopReg->setEnabled(false); + } + else + { + } + } +} + +void QmitkMatchPoint::OnSaveLogBtnPushed() +{ + QDateTime currentTime = QDateTime::currentDateTime(); + QString fileName = tr("registration_log_") + currentTime.toString(tr("yyyy-MM-dd_hh-mm-ss")) + + tr(".txt"); + fileName = QFileDialog::getSaveFileName(NULL, tr("Save registration log"), fileName, + tr("Text files (*.txt)")); + + if (fileName.isEmpty()) + { + QMessageBox::critical(NULL, tr("No file selected!"), + tr("Cannot save registration log file. Please selected a file.")); + } + else + { + std::ofstream file; + + std::ios_base::openmode iOpenFlag = std::ios_base::out | std::ios_base::trunc; + file.open(fileName.toStdString().c_str(), iOpenFlag); + + if (!file.is_open()) + { + mitkThrow() << "Cannot open or create specified file to save. File path: " + << fileName.toStdString(); + } + + file << this->m_Controls.m_teLog->toPlainText().toStdString() << std::endl; + + file.close(); + } + +} + +void QmitkMatchPoint::OnRegJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPoint::OnRegJobFinished() +{ + this->m_Working = false; + + this->GetRenderWindowPart()->RequestUpdate(); + + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); +}; + + +void QmitkMatchPoint::OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer + spResultRegistration, const QmitkRegistrationJob* pRegJob) +{ + mitk::DataNode::Pointer spResultRegistrationNode = mitk::generateRegistrationResultNode( + pRegJob->m_JobName, spResultRegistration, pRegJob->GetLoadedAlgorithm()->getUID()->toStr(), + pRegJob->m_MovingNodeUID, pRegJob->m_TargetNodeUID); + + if (pRegJob->m_StoreReg) + { + m_Controls.m_teLog->append( + QString(" Storing registration object in data manager ... ")); + + this->GetDataStorage()->Add(spResultRegistrationNode); + this->GetRenderWindowPart()->RequestUpdate(); + } + + if (m_Controls.m_checkMapEntity->checkState() == Qt::Checked) + { + QmitkMappingJob* pMapJob = new QmitkMappingJob(); + pMapJob->setAutoDelete(true); + + pMapJob->m_spInputData = pRegJob->m_spMovingData; + pMapJob->m_InputNodeUID = pRegJob->m_MovingNodeUID; + pMapJob->m_spRegNode = spResultRegistrationNode; + pMapJob->m_doGeometryRefinement = false; + pMapJob->m_spRefGeometry = pRegJob->m_spTargetData->GetGeometry()->Clone().GetPointer(); + + pMapJob->m_MappedName = pRegJob->m_JobName + std::string(" mapped moving data"); + pMapJob->m_allowUndefPixels = true; + pMapJob->m_paddingValue = 100; + pMapJob->m_allowUnregPixels = true; + pMapJob->m_errorValue = 200; + pMapJob->m_InterpolatorLabel = "Linear Interpolation"; + pMapJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; + + connect(pMapJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); + connect(pMapJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + Qt::BlockingQueuedConnection); + connect(pMapJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); + + m_Controls.m_teLog->append( + QString("Started mapping input data...")); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pMapJob); + } +}; + +void QmitkMatchPoint::OnMapJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPoint::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, + const QmitkMappingJob* job) +{ + m_Controls.m_teLog->append(QString("Mapped entity stored. Name: ") + + QString::fromStdString(job->m_MappedName) + QString("")); + + mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, + spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputNodeUID, + job->m_doGeometryRefinement, job->m_InterpolatorLabel); + this->GetDataStorage()->Add(spMappedNode); + this->GetRenderWindowPart()->RequestUpdate(); +}; + +void QmitkMatchPoint::OnAlgorithmIterated(QString info, bool hasIterationCount, + unsigned long currentIteration) +{ + if (hasIterationCount) + { + m_Controls.m_progBarIteration->setValue(currentIteration); + } + + m_Controls.m_teLog->append(info); +}; + +void QmitkMatchPoint::OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel) +{ + if (hasLevelCount) + { + m_Controls.m_progBarLevel->setValue(currentLevel); + } + + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPoint::OnAlgorithmStatusChanged(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString(" ")); +}; + +void QmitkMatchPoint::OnAlgorithmInfo(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPoint::OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection) +{ + // check for null selection + if (selection.IsNull()) + { + return; + } + + if (sourcepart != this) + { + UpdateAlgorithmSelection(selection); + } +} + +void QmitkMatchPoint::UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection) +{ + mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = + selection.Cast(); + + if (currentSelection) + { + mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = + currentSelection->GetSelectedAlgorithmInfo(); + + if (!infoVector.empty()) + { + // only the first selection is of interest, the rest will be skipped. + this->m_SelectedAlgorithmInfo = infoVector[0]; + } + } + + this->OnSelectedAlgorithmChanged(); +}; diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.h new file mode 100644 index 0000000000..7e5a4dc48f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.h @@ -0,0 +1,207 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __Q_MITK_MATCHPOINT_H +#define __Q_MITK_MATCHPOINT_H + +#include + +#include + +#include "ui_QmitkMatchPointControls.h" + +#include + +// MatchPoint +#include +#include +#include +#include +#include +#include + +#include + +class QmitkRegistrationJob; +class QmitkMappingJob; + +/*! +\brief MatchPoint + +\warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + +\sa QmitkFunctionality +\ingroup ${plugin_target}_internal +*/ +class QmitkMatchPoint : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPoint) + + QmitkMatchPoint(); + ~QmitkMatchPoint(); + +protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + /// \brief Called when the user clicks the GUI button + void OnMaskCheckBoxToggeled(bool checked); + void OnLoadAlgorithmButtonPushed(); + void OnSelectedAlgorithmChanged(); + + void OnStartRegBtnPushed(); + void OnStopRegBtnPushed(); + void OnSaveLogBtnPushed(); + + void OnRegJobError(QString err); + void OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, + const QmitkRegistrationJob* pRegJob); + void OnRegJobFinished(); + void OnMapJobError(QString err); + void OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job); + void OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration); + void OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel); + void OnAlgorithmStatusChanged(QString info); + void OnAlgorithmInfo(QString info); + +protected: + virtual void CreateQtPartControl(QWidget* parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& nodes); + +private: + + /** + * @brief Adapt the visibility of GUI elements depending on the current data loaded + */ + void AdaptFolderGUIElements(); + + void Error(QString msg); + + void UpdateAlgorithmList(); + + /** + * checks if appropriated nodes are selected in the data manager. If nodes are selected, + * they are stored m_MovingData and m_TargetData. It also sets the info lables accordingly. + * @return True: All inputs are set and valid (images). False: At least one input is not set + * or invalid */ + bool CheckInputs(); + + /** + * Updates the state of registration control buttons. Regarding to selected + * inputs, loaded algorithm and its state.*/ + void ConfigureRegistrationControls(); + + /** + * Configures the progress bars according to the chosen algorithm. + */ + void ConfigureProgressInfos(); + + /** Methods returns a list of all nodes in the data manager containing a registration wrapper. + * The list may be empty.*/ + mitk::DataStorage::SetOfObjects::Pointer GetRegNodes() const; + + /** Returns a proposal for a (unique) default reg job name */ + std::string GetDefaultRegJobName() const; + + /** Returns the display name of the passed node. Normally it is just node->GetName(). + * if the node contains a point set it is additionally checked if the point set node + * has a source node and its name will be added in parentheses.*/ + std::string GetInputNodeDisplayName(const mitk::DataNode* node) const; + + /** Returns the Pointer to the DLL info of the algorithm currently selected by the system. + The info is received via m_AlgorithmSelectionListener. + @return If there is no item selected the returning pointer + will be null. + */ + const map::deployment::DLLInfo* GetSelectedAlgorithmDLL() const; + + //! [Qt Selection Listener method and pointer] + /** + * @brief Method of berry::ISelectionListener that implements the selection listener functionality. + * @param sourcepart The workbench part responsible for the selection change. + * @param selection This parameter holds the current selection. + * + * @see ISelectionListener + */ + void OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection); + + void UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection); + + friend struct berry::SelectionChangedAdapter; + /** @brief this pointer holds the algorithm selection listener */ + QScopedPointer m_AlgorithmSelectionListener; + + ::map::deployment::DLLHandle::Pointer m_LoadedDLLHandle; + ::map::algorithm::RegistrationAlgorithmBase::Pointer m_LoadedAlgorithm; + ::map::deployment::DLLInfo::ConstPointer m_SelectedAlgorithmInfo; + + typedef map::algorithm::facet::IterativeAlgorithmInterface IIterativeAlgorithm; + typedef map::algorithm::facet::MultiResRegistrationAlgorithmInterface IMultiResAlgorithm; + typedef map::algorithm::facet::StoppableAlgorithmInterface IStoppableAlgorithm; + + mitk::DataNode::Pointer m_spSelectedTargetNode; + mitk::DataNode::Pointer m_spSelectedMovingNode; + /*Data of the selected target node that should be used for registration. + Can be the direct return of node->GetData(), but can also be a sub + set (like a special time frame).*/ + mitk::BaseData::ConstPointer m_spSelectedTargetData; + /*Data of the selected moving node that should be used for registration. + Can be the direct return of node->GetData(), but can also be a sub + set (like a special time frame).*/ + mitk::BaseData::ConstPointer m_spSelectedMovingData; + + mitk::DataNode::Pointer m_spSelectedTargetMaskNode; + mitk::DataNode::Pointer m_spSelectedMovingMaskNode; + /*Data of the selected target mask node that should be used for registration. + Can be the direct return of node->GetData(), but can also be a sub + set (like a special time frame).*/ + mitk::Image::ConstPointer m_spSelectedTargetMaskData; + /*Data of the selected moving mask node that should be used for registration. + Can be the direct return of node->GetData(), but can also be a sub + set (like a special time frame).*/ + mitk::Image::ConstPointer m_spSelectedMovingMaskData; + + // boolean variables to control visibility of GUI elements + bool m_CanLoadAlgorithm; + bool m_ValidInputs; + bool m_Working; + + QWidget* m_Parent; + Ui::MatchPointAdvancedControls m_Controls; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPointControls.ui b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPointControls.ui new file mode 100644 index 0000000000..c8fabaa8ca --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPointControls.ui @@ -0,0 +1,761 @@ + + + MatchPointAdvancedControls + + + + 0 + 0 + 396 + 850 + + + + + 5 + + + 5 + + + + + Loaded algorithm: + + + + + + + + 400 + 16777215 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Moving image/point set: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Target image/point set: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Masks + + + + 5 + + + 5 + + + + + Moving Mask: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Target Mask: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + + + true + + + + 200 + 0 + + + + 1 + + + false + + + false + + + false + + + + Selection + + + + 5 + + + 5 + + + + + + 75 + true + + + + Load an algorithm + + + + + + + Algorithm browser selection: + + + + + + + Load selected algorithm + + + + + + + true + + + false + + + Selected algorithm information: + + + true + + + 0 + + + -1 + + + + + + + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + TextLabel + + + + + label_Heading1 + m_teAlgorithmDetails + label_algo + label_algoInfo + m_pbLoadSelected + m_lbSelectedAlgorithm + + + + Execution + + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 75 + true + + + + Perform Registration + + + + + + + Registration job name: + + + + + + + Name of the resulting mapped image + + + Unnamed RegJob + + + + + + + Store registration + + + true + + + + + + + Generate + store mapped result + + + true + + + + + + + + + Start + + + + + + + Stop + + + + + + + + + + 0 + 0 + + + + Progress + + + false + + + + + + Resolution level: + + + + + + + 100 + + + 24 + + + false + + + %v/%m + + + + + + + Iterations: + + + + + + + 100 + + + 24 + + + false + + + %p% (%v/%m) + + + + + + + Log: + + + + + + + + 0 + 0 + + + + + 9 + + + + Qt::ScrollBarAlwaysOn + + + true + + + QTextEdit::NoWrap + + + true + + + + + + + + + Clear log on algorithm start + + + + + + + Save log to file + + + + + + + + + + + + + Settings + + + + 5 + + + 5 + + + + + + 75 + true + + + + Configure algorithm parameters + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + + + + + + + + + + QmitkAlgorithmProfileViewer + QWidget +
QmitkAlgorithmProfileViewer.h
+
+ + QmitkAlgorithmSettingsConfig + QWidget +
QmitkAlgorithmSettingsConfig.h
+
+
+ + + + + 5 + + + 5 + + + true + + + true + + + true + + +
diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.cpp new file mode 100644 index 0000000000..0ada6ea8ee --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.cpp @@ -0,0 +1,40 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h" + +#include "QmitkMatchPoint.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPoint, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h new file mode 100644 index 0000000000..2401631b2d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h @@ -0,0 +1,43 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator_h +#define org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_algorithmcontrol") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator + +#endif // org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator_h diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.framereg/CMakeLists.txt new file mode 100644 index 0000000000..00524a35ec --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_gui_qt_matchpoint_framereg) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_GUI_QT_MATCHPOINT_FRAME_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration MitkMatchPointRegistrationUI + PACKAGE_DEPENDS CTK|CTKCore +) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..01c46d8565 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/Manual.dox @@ -0,0 +1,64 @@ +/** +\page de_dkfz_matchpoint_mitk_gui_qt_algorithm_framereg The MatchPoint Motion/Frame Correction Plugin + +\imageMacro{"map-icon-run.png", "Icon of the MatchPoint Algorithm Control", 3} + +\li \ref MAP_FRAME_Introduction +\li \ref MAP_FRAME_Contact +\li \ref MAP_FRAME_Usage + +\section MAP_FRAME_Introduction Introduction +This plugin offers the user a way to use a selected registration algorithm in order to make a frame/motion correction +for a selected 3D+t images. The plugin is for example helpfull if you have a dynamic image with motion artifacts in same +time points and you want to reduce/remove this motion artifacts. +For the selection of an algorithm please see MatchPoint Algorithm Browser (\ref de_dkfz_matchpoint_mitk_gui_qt_algorithm_browser). + +\section MAP_FRAME_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_FRAME_Usage Usage +\imageMacro{"control_example.png" , "Example screenshot showing the plugin in use.", 15} +To use the plugin a registration algorithm must be loaded and the image must be selected, that should be corrected.\n +The correction is performed that every frame/timpoint of the image is registered to the first frame. And the corrected frames +is mapped in the same geometry then the first frame.\n +If an algorithm is loaded and input images are selected, the plugin will automatically switch to the "Execution" tab. + +\subsection MAP_FRAME_Usage_selection Algorithm selection tab +\imageMacro{step1_selection.png, "Details of the algorithm selection tab.", 6} +In this tab you can load/"book" the algorithm selected in the MatchPoint Algorithm Browser. In the tab you see the ID of the algorithm +selected by the browser and its profile information.\n +If you press "Load selected algorithm", the algorithm will be used by the plugin for the frame correction and the name of the algorithm occurs +in the text field "Loaded algorithm" (at the top of the plugin view).\n +At this point, it has no effect if you change the the selection in the browser. The plugin will keep the loaded algorithm until +you choose to load another one. + +\subsection MAP_FRAME_Usage_exec Execution tab +\imageMacro{step2_execution.png, "Details of the execution tab.", 8} +In this tab you can specify a name for the correction job (this will determine the names of the result nodes in the data manager).\n +"Start" will trigger the correction process. + +\subsection MAP_FRAME_Usage_settings Settings tab +\imageMacro{step3_settings.png, "Details of the settings tab.", 8} +In this tab, you can (1) define the mapping settings \ref MAP_FRAME_Mapper_Settings "(See details)", used for the corrected frames, or (2) parametrize the loaded algorithm (before it starts), if it offers any possibility to do so. +*/ + +\section MAP_FRAME_Mapper_Settings Mapper settings +For the mapping of corrected images, you have several settings available:\n +\li "Allow undefined pixels": Activate to handle pixels of the result image that are not in the field of view of the input image. This pixel will get the "padding value". +\li "Allow error pixels": Activate to handle pixels of the result image that can not be mapped because the registration does not support this part of the output image. This pixel will get the "error value". +\li "Interpolator": Set to choose the interpolation strategy that should be used for mapping. \ref MAP_FRAME_Interpolation "(see details)" + +\section MAP_FRAME_Interpolation Interpolation +You can choose from the following interpolation strategies:\n +\li "nearest neighbour": Use the value of the nearest pixel. Fastest, but high interpolation errors for gray value images. Right choice for label images or masks. +\li "Linear": Fast linear interpolation with often sufficient quality. Tends to blur edges. +\li "BSpline (3rd order)": Good trade off between time and quality. +\li "Windowed Sinc (Hamming)": Good interpolation quality but very time consuming. +\li "Windowed Sinc (Welch)": Good interpolation quality but very time consuming. + +\subsection MAP_FRAME_Usage_frame_selection Frame selection tab +\imageMacro{step4_frameselection.png, "Details of the frame selection tab.", 6} +In this tab you can specify the frames of the currently selected image that should be corrected. As default all frames of an image will be corrected. +If you only select specific frames, these frames will be corrected all other frames will be just copied unchanged. diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/control_example.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/control_example.png new file mode 100644 index 0000000000..ce47acf90b Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/control_example.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/framereg_example.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/framereg_example.png new file mode 100644 index 0000000000..46bd5debb3 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/framereg_example.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/map-icon-run.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/map-icon-run.png new file mode 100644 index 0000000000..7606e0e4d8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/map-icon-run.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step1_selection.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step1_selection.png new file mode 100644 index 0000000000..30e07c0d58 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step1_selection.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step2_execution.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step2_execution.png new file mode 100644 index 0000000000..0b231102fe Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step2_execution.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step3_settings.PNG b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step3_settings.PNG new file mode 100644 index 0000000000..eb4a71fdbb Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step3_settings.PNG differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step4_frameselection.PNG b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step4_frameselection.PNG new file mode 100644 index 0000000000..349cbd8242 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/UserManual/step4_frameselection.PNG differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..ae326e518f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup de_dkfz_matchpoint_mitk de.dkfz.matchpoint.mitk + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup de_dkfz_matchpoint_mitk_internal Internal + \ingroup de_dkfz_matchpoint_mitk + + \brief This subcategory includes the internal classes of the de.dkfz.matchpoint.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.framereg/files.cmake new file mode 100644 index 0000000000..40758303ee --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/files.cmake @@ -0,0 +1,43 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_framereg_Activator.cpp + QmitkMatchPointFrameCorrection.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointFrameCorrectionControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.h + src/internal/QmitkMatchPointFrameCorrection.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.framereg/manifest_headers.cmake new file mode 100644 index 0000000000..153ab01d04 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Frame Correction") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager org.mitk.matchpoint.core.helper) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.framereg/plugin.xml new file mode 100644 index 0000000000..80506cd356 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/resources/icon.png b/Plugins/org.mitk.gui.qt.matchpoint.framereg/resources/icon.png new file mode 100644 index 0000000000..7606e0e4d8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.framereg/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp new file mode 100644 index 0000000000..680480ae60 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.cpp @@ -0,0 +1,820 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_framereg_Activator.h" + +// Blueberry +#include +#include +#include +#include + +// Mitk +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qmitk +#include "QmitkMatchPointFrameCorrection.h" +#include +#include + +// Qt +#include +#include +#include +#include +#include + +// MatchPoint +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const std::string QmitkMatchPointFrameCorrection::VIEW_ID = + "org.mitk.views.matchpoint.algorithm.framereg"; + +QmitkMatchPointFrameCorrection::QmitkMatchPointFrameCorrection() + : m_Parent(NULL), m_LoadedDLLHandle(NULL), m_LoadedAlgorithm(NULL), m_CanLoadAlgorithm(false), + m_ValidInputs(false), m_Working(false) +{ + m_spSelectedTargetData = NULL; + m_spSelectedTargetMaskData = NULL; +} + +QmitkMatchPointFrameCorrection::~QmitkMatchPointFrameCorrection() +{ + // remove selection service + berry::ISelectionService* s = this->GetSite()->GetWorkbenchWindow()->GetSelectionService(); + + if (s) + { + s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); + } +} + +void QmitkMatchPointFrameCorrection::SetFocus() +{ +} + +void QmitkMatchPointFrameCorrection::CreateConnections() +{ + + connect(m_Controls.checkTargetMask, SIGNAL(toggled(bool)), this, + SLOT(OnMaskCheckBoxToggeled(bool))); + + // ------ + // Tab 1 - Shared library loading interface + // ------ + + connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); + + // ----- + // Tab 2 - Execution + // ----- + connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); + connect(m_Controls.m_pbSaveLog, SIGNAL(clicked()), this, SLOT(OnSaveLogBtnPushed())); + + // ----- + // Tab 4 - Frames + // ----- + connect(m_Controls.m_btnFrameSelAll, SIGNAL(clicked()), this, SLOT(OnFramesSelectAllPushed())); + connect(m_Controls.m_btnFrameDeSelAll, SIGNAL(clicked()), this, SLOT(OnFramesDeSelectAllPushed())); + connect(m_Controls.m_btnFrameInvert, SIGNAL(clicked()), this, SLOT(OnFramesInvertPushed())); + +} + +const map::deployment::DLLInfo* QmitkMatchPointFrameCorrection::GetSelectedAlgorithmDLL() const +{ + return m_SelectedAlgorithmInfo; +} + +void QmitkMatchPointFrameCorrection::OnMaskCheckBoxToggeled(bool checked) +{ + if (!m_Working) + { + CheckInputs(); + ConfigureRegistrationControls(); + } +}; + +void QmitkMatchPointFrameCorrection::OnSelectedAlgorithmChanged() +{ + std::stringstream descriptionString; + + ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); + + if (!currentItemInfo) + { + return; + } + + m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); + + m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( + currentItemInfo->getAlgorithmUID().getName())); + + // enable loading + m_CanLoadAlgorithm = true; + this->AdaptFolderGUIElements(); +} + +void QmitkMatchPointFrameCorrection::OnLoadAlgorithmButtonPushed() +{ + map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); + + if (!dllInfo) + { + Error(QString("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); + return; + } + + ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( + dllInfo->getLibraryFilePath()); + ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm + = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); + + if (tempAlgorithm.IsNull()) + { + Error(QString("Error. Cannot load selected algorithm.")); + return; + } + + this->m_LoadedAlgorithm = tempAlgorithm; + this->m_LoadedDLLHandle = tempDLLHandle; + + this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); + m_Controls.checkTargetMask->setChecked(false); + + this->AdaptFolderGUIElements(); + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); + this->m_Controls.m_tabs->setCurrentIndex(1); +} + +void QmitkMatchPointFrameCorrection::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); + + m_Controls.m_teLog->append(QString("") + msg + QString("")); +} + +void QmitkMatchPointFrameCorrection::AdaptFolderGUIElements() +{ + m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); +} + +void QmitkMatchPointFrameCorrection::CreateQtPartControl(QWidget* parent) +{ + + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + m_Parent = parent; + + m_Controls.checkTargetMask->setChecked(false); + m_Controls.m_tabs->setCurrentIndex(0); + + m_Controls.m_mapperSettings->AllowSampling(false); + + m_AlgorithmSelectionListener.reset(new + berry::SelectionChangedAdapter(this, + &QmitkMatchPointFrameCorrection::OnAlgorithmSelectionChanged)); + + // register selection listener + GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( + m_AlgorithmSelectionListener.data()); + + this->CreateConnections(); + this->AdaptFolderGUIElements(); + this->CheckInputs(); + this->ConfigureProgressInfos(); + this->ConfigureRegistrationControls(); + + berry::ISelection::ConstPointer selection = + GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); + + this->UpdateAlgorithmSelection(selection); +} + +bool QmitkMatchPointFrameCorrection::CheckInputs() +{ + bool validTarget = false; + + bool validTargetMask = false; + + mitk::DataNode::Pointer oldTargetNode = m_spSelectedTargetNode; + + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + + if (m_LoadedAlgorithm.IsNull()) + { + m_Controls.m_lbLoadedAlgorithmName->setText( + QString("No algorithm seleted!")); + m_spSelectedTargetNode = NULL; + m_spSelectedTargetData = NULL; + + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + else + { + QList nodes = this->GetDataManagerSelection(); + + mitk::Image* targetImage = NULL; + mitk::PointSet* targetPointSet = NULL; + + mitk::Image* targetMaskImage = NULL; + + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; + + MaskRegInterface* pMaskInterface = dynamic_cast(m_LoadedAlgorithm.GetPointer()); + + if (nodes.count() < 1) + { + m_Controls.m_lbTargetName->setText(QString("no data selected!")); + m_spSelectedTargetNode = NULL; + m_spSelectedTargetData = NULL; + } + else + { + m_spSelectedTargetNode = nodes.front(); + m_spSelectedTargetData = m_spSelectedTargetNode->GetData(); + targetImage = dynamic_cast(m_spSelectedTargetNode->GetData()); + + if (targetImage) + { + if (targetImage->GetTimeSteps() < 1) + { + m_Controls.m_lbTargetName->setText(QString("Image has no mulitple time steps")); + } + else if (targetImage->GetDimension() != m_LoadedAlgorithm->getTargetDimensions() + 1) + { + m_Controls.m_lbTargetName->setText(QString("wrong image dimension. ") + + QString::number(m_LoadedAlgorithm->getTargetDimensions()) + QString("D+t needed")); + } + else + { + validTarget = true; + } + } + else + { + m_Controls.m_lbTargetName->setText(QString("no supported data selected!")); + } + + nodes.removeFirst(); + } + + if (m_Controls.checkTargetMask->isChecked()) + { + if (nodes.count() < 1) + { + m_Controls.m_lbTargetMaskName->setText(QString("no data selected!")); + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + else + { + m_spSelectedTargetMaskNode = nodes.front(); + m_spSelectedTargetMaskData = NULL; + targetMaskImage = dynamic_cast(m_spSelectedTargetMaskNode->GetData()); + + bool isMask = maskPredicate->CheckNode(m_spSelectedTargetMaskNode); + + if (!isMask) + { + m_Controls.m_lbTargetMaskName->setText(QString("no mask selected!")); + } + else if (targetMaskImage && pMaskInterface) + { + m_spSelectedTargetMaskData = targetMaskImage; + validTargetMask = true; + } + else + { + m_Controls.m_lbTargetMaskName->setText( + QString("no supported data selected!")); + } + } + + } + else + { + m_Controls.m_lbTargetMaskName->setText(QString("mask deactivated")); + validTargetMask = true; + m_spSelectedTargetMaskNode = NULL; + m_spSelectedTargetMaskData = NULL; + } + + } + + if (validTarget) + { + m_Controls.m_lbTargetName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedTargetNode))); + + if (oldTargetNode != m_spSelectedTargetNode) + { + ConfigureFrameList(); + } + } + else + { + m_Controls.m_listFrames->clear(); + } + + if (validTargetMask && m_Controls.checkTargetMask->isChecked()) + { + m_Controls.m_lbTargetMaskName->setText(QString::fromStdString(GetInputNodeDisplayName( + m_spSelectedTargetMaskNode))); + } + + m_ValidInputs = validTarget && validTargetMask; + return m_ValidInputs; +} + +std::string QmitkMatchPointFrameCorrection::GetInputNodeDisplayName(const mitk::DataNode* node) +const +{ + std::string result = "UNDEFINED/NULL"; + + if (node) + { + result = node->GetName(); + + const mitk::PointSet* pointSet = dynamic_cast(node->GetData()); + + if (pointSet) + { + mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(node); + + if (sources.IsNotNull() && sources->Size() > 0) + { + result = result + " (" + sources->GetElement(0)->GetName() + ")"; + } + + } + } + + return result; +} + +mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPointFrameCorrection::GetRegNodes() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); + mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); + + for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); + ++pos) + { + if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + result->push_back(*pos); + } + } + + return result; +} + +std::string QmitkMatchPointFrameCorrection::GetDefaultJobName() const +{ + + mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); + mitk::DataStorage::SetOfObjects::ElementIdentifier newIndex = 0; + + bool isUnique = false; + + std::string baseName = "corrected #"; + + if (m_spSelectedTargetNode.IsNotNull()) + { + baseName = m_spSelectedTargetNode->GetName() + "corrected #"; + } + + std::string result = baseName; + + while (!isUnique) + { + ++newIndex; + result = baseName + ::map::core::convert::toStr(newIndex); + isUnique = this->GetDataStorage()->GetNamedNode(result) == NULL; + } + + return result; +} + +void QmitkMatchPointFrameCorrection::ConfigureRegistrationControls() +{ + m_Controls.m_tabSelection->setEnabled(!m_Working); + m_Controls.m_leRegJobName->setEnabled(!m_Working); + m_Controls.groupMasks->setEnabled(!m_Working); + + m_Controls.m_pbStartReg->setEnabled(false); + + m_Controls.m_lbTargetMaskName->setVisible(m_Controls.checkTargetMask->isChecked()); + + if (m_LoadedAlgorithm.IsNotNull()) + { + m_Controls.m_tabSettings->setEnabled(!m_Working); + m_Controls.m_tabExclusion->setEnabled(!m_Working); + m_Controls.m_tabExecution->setEnabled(true); + m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); + m_Controls.m_leRegJobName->setEnabled(!m_Working); + + typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; + const MaskRegInterface* pMaskReg = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + m_Controls.groupMasks->setVisible(pMaskReg != NULL); + + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); + } + else + { + m_Controls.m_tabSettings->setEnabled(false); + m_Controls.m_tabExclusion->setEnabled(false); + m_Controls.m_tabExecution->setEnabled(false); + this->m_Controls.m_lbLoadedAlgorithmName->setText( + QString("no algorithm loaded!")); + m_Controls.groupMasks->setVisible(false); + } + + if (!m_Working) + { + this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultJobName())); + } +} + +void QmitkMatchPointFrameCorrection::ConfigureProgressInfos() +{ + const IIterativeAlgorithm* pIterative = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + const IMultiResAlgorithm* pMultiRes = dynamic_cast + (m_LoadedAlgorithm.GetPointer()); + + m_Controls.m_progBarIteration->setVisible(pIterative); + m_Controls.m_lbProgBarIteration->setVisible(pIterative); + + + if (pIterative) + { + QString format = "%p% (%v/%m)"; + + if (!pIterative->hasMaxIterationCount()) + { + format = "%v"; + m_Controls.m_progBarIteration->setMaximum(0); + } + else + { + m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); + } + + m_Controls.m_progBarIteration->setFormat(format); + } + + if (pMultiRes) + { + m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); + + } + else + { + m_Controls.m_progBarLevel->setMaximum(1); + } + + m_Controls.m_progBarIteration->reset(); + m_Controls.m_progBarLevel->reset(); + m_Controls.m_progBarFrame->reset(); +} + +void QmitkMatchPointFrameCorrection::ConfigureFrameList() +{ + m_Controls.m_listFrames->clear(); + + if (m_spSelectedTargetData.IsNotNull()) + { + mitk::TimeGeometry::ConstPointer tg = m_spSelectedTargetData->GetTimeGeometry(); + + for (unsigned int i = 1; i < tg->CountTimeSteps(); ++i) + { + QString lable = "Timepoint #" + QString::number(i) + QString(" (") + QString::number( + tg->GetMinimumTimePoint(i)) + QString(" ms - " + QString::number(tg->GetMaximumTimePoint( + i)) + QString(" ms)")); + QListWidgetItem* item = new QListWidgetItem(lable, m_Controls.m_listFrames); + item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + item->setCheckState(Qt::Checked); + } + } +} + +void QmitkMatchPointFrameCorrection::OnFramesSelectAllPushed() +{ + for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) + { + QListWidgetItem* item = m_Controls.m_listFrames->item(row); + item->setCheckState(Qt::Checked); + } +}; + +void QmitkMatchPointFrameCorrection::OnFramesDeSelectAllPushed() +{ + for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) + { + QListWidgetItem* item = m_Controls.m_listFrames->item(row); + item->setCheckState(Qt::Unchecked); + } +}; + +void QmitkMatchPointFrameCorrection::OnFramesInvertPushed() +{ + for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) + { + QListWidgetItem* item = m_Controls.m_listFrames->item(row); + + if (item->checkState() == Qt::Unchecked) + { + item->setCheckState(Qt::Checked); + } + else + { + item->setCheckState(Qt::Unchecked); + } + } +}; + +mitk::TimeFramesRegistrationHelper::IgnoreListType +QmitkMatchPointFrameCorrection::GenerateIgnoreList() const +{ + mitk::TimeFramesRegistrationHelper::IgnoreListType result; + + for (unsigned int row = 0; row < m_Controls.m_listFrames->count(); row++) + { + QListWidgetItem* item = m_Controls.m_listFrames->item(row); + + if (item->checkState() == Qt::Unchecked) + { + result.push_back(row + 1); + } + } + + return result; +} + +void QmitkMatchPointFrameCorrection::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes) +{ + if (!m_Working) + { + CheckInputs(); + ConfigureRegistrationControls(); + } +} + +void QmitkMatchPointFrameCorrection::OnStartRegBtnPushed() +{ + this->m_Working = true; + + //////////////////////////////// + //configure GUI + this->ConfigureProgressInfos(); + + m_Controls.m_progBarIteration->reset(); + m_Controls.m_progBarLevel->reset(); + + this->ConfigureRegistrationControls(); + + if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) + { + this->m_Controls.m_teLog->clear(); + } + + + ///////////////////////// + //create job and put it into the thread pool + QmitkFramesRegistrationJob* pJob = new QmitkFramesRegistrationJob(m_LoadedAlgorithm); + pJob->setAutoDelete(true); + + pJob->m_spTargetData = m_spSelectedTargetData; + pJob->m_TargetNodeUID = mitk::EnsureUID(this->m_spSelectedTargetNode); + pJob->m_IgnoreList = this->GenerateIgnoreList(); + + if (m_spSelectedTargetMaskData.IsNotNull()) + { + pJob->m_spTargetMask = m_spSelectedTargetMaskData; + pJob->m_TargetMaskNodeUID = mitk::EnsureUID(this->m_spSelectedTargetMaskNode); + } + + pJob->m_MappedName = m_Controls.m_leRegJobName->text().toStdString(); + + m_Controls.m_mapperSettings->ConfigureJobSettings(pJob); + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); + connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); + connect(pJob, SIGNAL(ResultIsAvailable(mitk::Image::Pointer, const QmitkFramesRegistrationJob*)), + this, SLOT(OnMapResultIsAvailable(mitk::Image::Pointer, const QmitkFramesRegistrationJob*)), + Qt::BlockingQueuedConnection); + + connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); + connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, + SLOT(OnAlgorithmStatusChanged(QString))); + connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, + SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); + connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, + bool, unsigned long))); + connect(pJob, SIGNAL(FrameRegistered(double)), this, SLOT(OnFrameRegistered(double))); + connect(pJob, SIGNAL(FrameMapped(double)), this, SLOT(OnFrameMapped(double))); + connect(pJob, SIGNAL(FrameProcessed(double)), this, SLOT(OnFrameProcessed(double))); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + +void QmitkMatchPointFrameCorrection::OnSaveLogBtnPushed() +{ + QDateTime currentTime = QDateTime::currentDateTime(); + QString fileName = tr("registration_log_") + currentTime.toString(tr("yyyy-MM-dd_hh-mm-ss")) + + tr(".txt"); + fileName = QFileDialog::getSaveFileName(NULL, tr("Save registration log"), fileName, + tr("Text files (*.txt)")); + + if (fileName.isEmpty()) + { + QMessageBox::critical(NULL, tr("No file selected!"), + tr("Cannot save registration log file. Please selected a file.")); + } + else + { + std::ofstream file; + + std::ios_base::openmode iOpenFlag = std::ios_base::out | std::ios_base::trunc; + file.open(fileName.toStdString().c_str(), iOpenFlag); + + if (!file.is_open()) + { + mitkThrow() << "Cannot open or create specified file to save. File path: " + << fileName.toStdString(); + } + + file << this->m_Controls.m_teLog->toPlainText().toStdString() << std::endl; + + file.close(); + } +} + +void QmitkMatchPointFrameCorrection::OnRegJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPointFrameCorrection::OnRegJobFinished() +{ + this->m_Working = false; + + this->GetRenderWindowPart()->RequestUpdate(); + + this->CheckInputs(); + this->ConfigureRegistrationControls(); + this->ConfigureProgressInfos(); +}; + + +void QmitkMatchPointFrameCorrection::OnMapResultIsAvailable(mitk::Image::Pointer spMappedData, + const QmitkFramesRegistrationJob* job) +{ + m_Controls.m_teLog->append(QString("Corrected image stored. Name: ") + + QString::fromStdString(job->m_MappedName) + QString("")); + + mitk::DataNode::Pointer spResultNode = mitk::generateMappedResultNode(job->m_MappedName, + spMappedData.GetPointer(), "", job->m_TargetNodeUID, false, job->m_InterpolatorLabel); + + this->GetDataStorage()->Add(spResultNode, this->m_spSelectedTargetNode); + this->GetRenderWindowPart()->RequestUpdate(); +}; + +void QmitkMatchPointFrameCorrection::OnMapJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPointFrameCorrection::OnAlgorithmIterated(QString info, bool hasIterationCount, + unsigned long currentIteration) +{ + if (hasIterationCount) + { + m_Controls.m_progBarIteration->setValue(currentIteration); + } + + m_Controls.m_teLog->append(info); +}; + +void QmitkMatchPointFrameCorrection::OnLevelChanged(QString info, bool hasLevelCount, + unsigned long currentLevel) +{ + if (hasLevelCount) + { + m_Controls.m_progBarLevel->setValue(currentLevel); + } + + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPointFrameCorrection::OnAlgorithmStatusChanged(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString(" ")); +}; + +void QmitkMatchPointFrameCorrection::OnAlgorithmInfo(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPointFrameCorrection::OnFrameProcessed(double progress) +{ + m_Controls.m_teLog->append(QString("Frame processed...")); + m_Controls.m_progBarFrame->setValue(100 * progress); +}; + +void QmitkMatchPointFrameCorrection::OnFrameRegistered(double progress) +{ + m_Controls.m_teLog->append(QString("Frame registered...")); + m_Controls.m_progBarFrame->setValue(100 * progress); +}; + +void QmitkMatchPointFrameCorrection::OnFrameMapped(double progress) +{ + m_Controls.m_teLog->append(QString("Frame mapped...")); + m_Controls.m_progBarFrame->setValue(100 * progress); +}; + +void QmitkMatchPointFrameCorrection::OnAlgorithmSelectionChanged(const + berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection) +{ + // check for null selection + if (selection.IsNull()) + { + return; + } + + if (sourcepart != this) + { + UpdateAlgorithmSelection(selection); + } +} + +void QmitkMatchPointFrameCorrection::UpdateAlgorithmSelection(berry::ISelection::ConstPointer + selection) +{ + mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = + selection.Cast(); + + if (currentSelection) + { + mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = + currentSelection->GetSelectedAlgorithmInfo(); + + if (!infoVector.empty()) + { + // only the first selection is of interest, the rest will be skipped. + this->m_SelectedAlgorithmInfo = infoVector[0]; + } + } + + this->OnSelectedAlgorithmChanged(); +}; diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.h b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.h new file mode 100644 index 0000000000..d815dad6b1 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrection.h @@ -0,0 +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. + +===================================================================*/ + + +#ifndef __Q_MITK_MATCHPOINT_FRAME_CORRECTION_H +#define __Q_MITK_MATCHPOINT_FRAME_CORRECTION_H + +#include + +#include + +#include "ui_QmitkMatchPointFrameCorrectionControls.h" + +#include + +// MatchPoint +#include +#include +#include +#include +#include +#include + +#include +#include + +/*! +\brief View for motion artefact correction of images. + +The view utalizes MatchPoint registration algorithms and the mitk::TimeFramesRegistrationHelper and implemnts the GUI +business logic to make frame correction aka motion artefact correction on 3D+t images. + +*/ +class QmitkMatchPointFrameCorrection : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPointFrameCorrection) + + QmitkMatchPointFrameCorrection(); + ~QmitkMatchPointFrameCorrection(); + +protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + /// \brief Called when the user clicks the GUI button + void OnMaskCheckBoxToggeled(bool checked); + void OnLoadAlgorithmButtonPushed(); + void OnSelectedAlgorithmChanged(); + + void OnStartRegBtnPushed(); + void OnSaveLogBtnPushed(); + + void OnFramesSelectAllPushed(); + void OnFramesDeSelectAllPushed(); + void OnFramesInvertPushed(); + + void OnRegJobError(QString err); + void OnRegJobFinished(); + void OnMapJobError(QString err); + void OnMapResultIsAvailable(mitk::Image::Pointer spMappedData, + const QmitkFramesRegistrationJob* job); + void OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration); + void OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel); + void OnAlgorithmStatusChanged(QString info); + void OnAlgorithmInfo(QString info); + void OnFrameProcessed(double progress); + void OnFrameRegistered(double progress); + void OnFrameMapped(double progress); + +protected: + virtual void CreateQtPartControl(QWidget* parent); + + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& nodes); + +private: + + /** + * @brief Adapt the visibility of GUI elements depending on the current data loaded + */ + void AdaptFolderGUIElements(); + + void Error(QString msg); + + void UpdateAlgorithmList(); + + /** + * checks if appropriated nodes are selected in the data manager. If nodes are selected, + * they are stored m_MovingData and m_TargetData. It also sets the info lables accordingly. + * @return True: All inputs are set and valid (images). False: At least one input is not set + * or invalid */ + bool CheckInputs(); + + /** + * Updates the state of registration control buttons. Regarding to selected + * inputs, loaded algorithm and its state.*/ + void ConfigureRegistrationControls(); + + /** + * Configures the progress bars according to the chosen algorithm. + */ + void ConfigureProgressInfos(); + + /**configure the frame list widget based on the selected target.*/ + void ConfigureFrameList(); + + /**generates the ignore list based on the frame list widget selection.*/ + mitk::TimeFramesRegistrationHelper::IgnoreListType GenerateIgnoreList() const; + + /** Methods returns a list of all nodes in the data manager containing a registration wrapper. + * The list may be empty.*/ + mitk::DataStorage::SetOfObjects::Pointer GetRegNodes() const; + + /** Returns a proposal for a (unique) default reg job name */ + std::string GetDefaultJobName() const; + + /** Returns the display name of the passed node. Normally it is just node->GetName(). + * if the node contains a point set it is additionally checked if the point set node + * has a source node and its name will be added in parentheses.*/ + std::string GetInputNodeDisplayName(const mitk::DataNode* node) const; + + /** Returns the Pointer to the DLL info of the algorithm currently selected by the system. + The info is received via m_AlgorithmSelectionListener. + @return If there is no item selected the returning pointer + will be null. + */ + const map::deployment::DLLInfo* GetSelectedAlgorithmDLL() const; + + //! [Qt Selection Listener method and pointer] + /** + * @brief Method of berry::ISelectionListener that implements the selection listener functionality. + * @param sourcepart The workbench part responsible for the selection change. + * @param selection This parameter holds the current selection. + * + * @see ISelectionListener + */ + void OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, + const berry::ISelection::ConstPointer& selection); + + void UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection); + + friend struct berry::SelectionChangedAdapter; + /** @brief this pointer holds the algorithm selection listener */ + QScopedPointer m_AlgorithmSelectionListener; + + ::map::deployment::DLLHandle::Pointer m_LoadedDLLHandle; + ::map::algorithm::RegistrationAlgorithmBase::Pointer m_LoadedAlgorithm; + ::map::deployment::DLLInfo::ConstPointer m_SelectedAlgorithmInfo; + + typedef map::algorithm::facet::IterativeAlgorithmInterface IIterativeAlgorithm; + typedef map::algorithm::facet::MultiResRegistrationAlgorithmInterface IMultiResAlgorithm; + typedef map::algorithm::facet::StoppableAlgorithmInterface IStoppableAlgorithm; + + mitk::DataNode::Pointer m_spSelectedTargetNode; + /*Data of the selected target node that should be used for registration. + Can be the direct return of node->GetData(), but can also be a sub + set (like a special time frame).*/ + mitk::BaseData::ConstPointer m_spSelectedTargetData; + + mitk::DataNode::Pointer m_spSelectedTargetMaskNode; + mitk::Image::ConstPointer m_spSelectedTargetMaskData; + + // boolean variables to control visibility of GUI elements + bool m_CanLoadAlgorithm; + bool m_ValidInputs; + bool m_Working; + + QWidget* m_Parent; + Ui::MatchPointFrameCorrectionControls m_Controls; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrectionControls.ui b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrectionControls.ui new file mode 100644 index 0000000000..421890915f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/QmitkMatchPointFrameCorrectionControls.ui @@ -0,0 +1,680 @@ + + + MatchPointFrameCorrectionControls + + + + 0 + 0 + 348 + 850 + + + + + 5 + + + 5 + + + + + Loaded algorithm: + + + + + + + + 400 + 16777215 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Image: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + Masks + + + + 5 + + + 5 + + + + + Target Mask: + + + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + + + true + + + + 200 + 0 + + + + 1 + + + false + + + false + + + false + + + + Selection + + + + 5 + + + 5 + + + + + + 75 + true + + + + Load an algorithm + + + + + + + Algorithm browser selection: + + + + + + + Load selected algorithm + + + + + + + true + + + false + + + Selected algorithm information: + + + true + + + 0 + + + -1 + + + + + + + + + + QFrame::StyledPanel + + + 2 + + + 1 + + + TextLabel + + + + + label_Heading1 + m_teAlgorithmDetails + label_algo + label_algoInfo + m_pbLoadSelected + m_lbSelectedAlgorithm + + + + Execution + + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 75 + true + + + + Perform frame correction + + + + + + + Correction job name: + + + + + + + Name of the resulting mapped image + + + Unnamed RegJob + + + + + + + + + Start + + + + + + + + + + 0 + 0 + + + + Progress + + + false + + + + + + Frames: + + + + + + + 24 + + + + + + + Resolution level: + + + + + + + 100 + + + 24 + + + false + + + %v/%m + + + + + + + Iterations: + + + + + + + 100 + + + 24 + + + false + + + %p% (%v/%m) + + + + + + + Log: + + + + + + + + 0 + 0 + + + + + 9 + + + + Qt::ScrollBarAlwaysOn + + + true + + + QTextEdit::NoWrap + + + true + + + + + + + + + Clear log on algorithm start + + + + + + + Save log to file + + + + + + + + + + + + + Settings + + + + 5 + + + 5 + + + + + + 75 + true + + + + Configure mapping parameters + + + + + + + + + + + 75 + true + + + + Configure algorithm parameters + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + + + + + + Frame selection + + + + + + Select frames/timepoints that should be corrected: + + + + + + + + + + + + Select all + + + + + + + Deselect all + + + + + + + Invert + + + + + + + + + + + + + + QmitkAlgorithmProfileViewer + QWidget +
QmitkAlgorithmProfileViewer.h
+
+ + QmitkAlgorithmSettingsConfig + QWidget +
QmitkAlgorithmSettingsConfig.h
+
+ + QmitkMapperSettingsWidget + QWidget +
QmitkMapperSettingsWidget.h
+ 1 +
+
+ + + + + 5 + + + 5 + + + true + + + true + + + true + + +
diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.cpp new file mode 100644 index 0000000000..caeb744749 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.cpp @@ -0,0 +1,40 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_framereg_Activator.h" + +#include "QmitkMatchPointFrameCorrection.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_framereg_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_framereg_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPointFrameCorrection, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_framereg_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_framereg_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.h new file mode 100644 index 0000000000..b98000b8d6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.framereg/src/internal/org_mitk_gui_qt_matchpoint_framereg_Activator.h @@ -0,0 +1,42 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef org_mitk_gui_qt_matchpoint_framereg_Activator_h +#define org_mitk_gui_qt_matchpoint_framereg_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_framereg_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_framereg") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_matchpoint_framereg_Activator + +#endif // org_mitk_gui_qt_matchpoint_framereg_Activator diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.mapper/CMakeLists.txt new file mode 100644 index 0000000000..051c86ee0d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_matchpoint_mapper) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_GUI_QT_MATCHPOINT_MAPPER_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration MitkMatchPointRegistrationUI +) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..7ca6d839bb --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/Manual.dox @@ -0,0 +1,87 @@ +/** +\page org_mitk_gui_qt_matchpoint_mapper The MatchPoint Image Mapper View + +\imageMacro{map-icon-map.png, "Icon of the MatchPoint Image Mapper",3} + +\li \ref MAP_MAPPER_Introduction +\li \ref MAP_MAPPER_Contact +\li \ref MAP_MAPPER_Usage + +\section MAP_MAPPER_Introduction Introduction +This view offers the possibility to map any image or point set in the data manager using a user selected registration object. +Using the Mapper to map images the user can control the field of view (image geometry) the image should be mapped into, as well as +interpolation strategy that should be used.\n +It is one of several MatchPoint registration plugins.\n +Typical usage scenarios\n +\li You have registered image I1 onto image I2. Now you want to transfer the segmentation of I1 to I2 in order to evaluate I2 within this mapped segmentation using \ref org_mitk_views_imagestatistics . +\li You have registered image I1 onto image I2. Now you want to map I3 (e.g. an other MRI sequence of the same session) also onto I2 with the same registration. +\li You have registered image I1 onto image I2. Now you want to map a segmentation done on I1 also onto I2 with the same registration. +\li You have registered image I1 onto image I2. Now you want to map a point set of image I1 also onto I2 with the same registration. + +\section MAP_MAPPER_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_MAPPER_Usage Usage +\imageMacro{mapper-examplescreen.png, "Example screenshot showing the Mapper plugin in use.", 14} +To use the mapper at least an input data (image or point set) must be selected. Additionally you may select a registration object and a reference image. +Registration objects are marked with a small blue icon (e.g. the data "Registration" in the data manager of the screen shot above). +The Reference image defines the geometry (field of view, orientation, spacing) that should be used for the result image. +By default the view will try to automatically determine the reference image (by default it is the target image of the selected registration). +If auto selection cannot determine the reference it will choose the input image as reference. +The reference image can be also defined by the user explicitly by activating manual selection.\n +REMARK: If you map point sets you can ignore the reference image slot. It has no affect.\n +You can multiselect registration and data (press the CTRL-key while selecting the nodes in the data manager). +The Mapper will automatically sort the selections in the correct "slots" of the view.\n +REMARK: The mapping results will be added as child nodes to the used input node.\n +REMARK: If you do not select an registration the view will assume that you make an identity transform. This is a convinient way if you +just want to resample an image into the geometry of an other image (when no registration is needed). Also in this use case you can take +adventage of the different interpolation and sub/super sampling strategies. + +\imageMacro{mapper.png, "Details of the mapper view.", 8} +(1) The currently selected registration, that will be used for mapping.\n +(2) The currently selected input data, that will be mapped.\n +(3) The currently (automatically or by user) selected reference image, that defines the geometry of the result.\n +(4) The name of the result data in the data manger.\n +(5) The start button(s) to commence the mapping process. For details regarding the two options see \ref MAP_MAPPER_Refine.\n +(6) Log windows with messages regarding the mapping process.\n\n + +Every "slot" has the ability to be locked. If locked the last selection will be kept, regardless the current selection in the data manager. +You can use this for example to lock the registration, if you want to map multiple images. Doing so it is enough to just select the next image +in the data manager. To lock a slot, click at the "lock" button at the right side (see example images below). +\imageMacro{node-unlocked.png, "Unlocked slot/node (default state). Changes with the selections in the data manager.",6} +\imageMacro{ node-locked.png, "Locked slot/node. Stays, regardless the selections in the data manager.",6} + +\section MAP_MAPPER_Refine Mapping or geometry refinement +The mapper view offers two options to map images:\n +\li "Map" (default) +\li "Refine geometry" +For images "Map" fills the pixels of the output image by interpolating input image pixels using the registration object. This option always works. +But may take longer and introduces interpolation errors, because a new image is resampled.\n +The second option "Refine geometry" is only offered, if the registration (more precise its inverse kernel) is matrix based and the selected data is an image. +In this case it just clones the image and refines the image geometry (origin, orientation, ...); thus no interpolation artefacts are introduced. +\remark If you want to use a mapped image in conjunction with the statistic plugin and an mask of the reference image, you must use "Map" to ensure the same geometry. +Otherwise the statistic plugin will fail. + +\section MAP_MAPPER_Settings Settings +If you map the image (and not just refine the geometry), you have several settings available:\n +\li "Allow undefined pixels": Activate to handle pixels of the result image that are not in the field of view of the input image. This pixel will get the "padding value". +\li "Allow error pixels": Activate to handle pixels of the result image that can not be mapped because the registration does not support this part of the output image. This pixel will get the "error value". +\li "Interpolator": Set to choose the interpolation strategy that should be used for mapping. +\li "Activate super/sub sampling": Activate if you want to use origin and orientation of the reference image but want to alter the spacing. + +\section MAP_MAPPER_Interpolation Interpolation +You can choose from the following interpolation strategies:\n +\li "nearest neighbour": Use the value of the nearest pixel. Fastest, but high interpolation errors for gray value images. Right choice for label images or masks. +\li "Linear": Fast linear interpolation with often sufficient quality. Tends to blur edges. +\li "BSpline (3rd order)": Good trade off between time and quality. +\li "Windowed Sinc (Hamming)": Good interpolation quality but very time consuming. +\li "Windowed Sinc (Welch)": Good interpolation quality but very time consuming. + +\section MAP_MAPPER_Masks Handling of masks/segmentations +If you select an mask as input image, the plugin will be automatically reconfigured to settings that are suitable for the task of mapping masks. +Most importantly the interpolator will be set to "nearest neighbour". + +*/ + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/map-icon-map.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/map-icon-map.png new file mode 100644 index 0000000000..2218a9856c Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/map-icon-map.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-examplescreen.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-examplescreen.png new file mode 100644 index 0000000000..bfef5a7e61 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-examplescreen.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-settings.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-settings.png new file mode 100644 index 0000000000..3f67d61e62 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper-settings.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper.png new file mode 100644 index 0000000000..aa51c5657c Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/mapper.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-locked.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-locked.png new file mode 100644 index 0000000000..2b8c73709d Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-locked.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-unlocked.png b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-unlocked.png new file mode 100644 index 0000000000..40bb1a1e8a Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/UserManual/node-unlocked.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..620df9f269 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_matchpoint_mapper org.mitk.gui.qt.mapper + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_internal Internal + \ingroup org_mitk + + \brief This subcategory includes the internal classes of the org.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.mapper/files.cmake new file mode 100644 index 0000000000..f414101888 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/files.cmake @@ -0,0 +1,45 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_mapper_Activator.cpp + QmitkMatchPointMapper.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointMapper.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.h + src/internal/QmitkMatchPointMapper.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.xpm + resources/icon_lock.png + resources/icon_unlock.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.mapper/manifest_headers.cmake new file mode 100644 index 0000000000..12756751ed --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Data Mapper") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.mapper/plugin.xml new file mode 100644 index 0000000000..64a25ac2d3 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/resources/icon.xpm b/Plugins/org.mitk.gui.qt.matchpoint.mapper/resources/icon.xpm new file mode 100644 index 0000000000..37d18007f9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/resources/icon.xpm @@ -0,0 +1,251 @@ +/* XPM */ +static char *mapiconmap[] = { +/* columns rows colors chars-per-pixel */ +"32 32 213 2", +" c #163C01", +". c #173E01", +"X c #163E04", +"o c #173D07", +"O c #183E03", +"+ c #253001", +"@ c #1E3831", +"# c #333D37", +"$ c #5E0101", +"% c #580601", +"& c #510B01", +"* c #560D08", +"= c #560B0F", +"- c #471401", +"; c #561201", +": c #550D11", +"> c #4C191F", +", c #511312", +"< c #610101", +"1 c #650101", +"2 c #660101", +"3 c #680101", +"4 c #6F0101", +"5 c #710101", +"6 c #740101", +"7 c #770101", +"8 c #7A0101", +"9 c #7C0101", +"0 c #452601", +"q c #402F01", +"w c #5F2401", +"e c #542801", +"r c #472316", +"t c #632303", +"y c #612401", +"u c #652603", +"i c #662703", +"p c #6D2001", +"a c #4A153D", +"s c #194001", +"d c #1A4201", +"f c #1C4301", +"g c #1D4209", +"h c #174011", +"j c #174216", +"k c #1C411D", +"l c #204902", +"z c #244E02", +"x c #275202", +"c c #254910", +"v c #2C4E1E", +"b c #326103", +"n c #386804", +"m c #3C6E04", +"M c #3F7104", +"N c #184426", +"B c #154D27", +"V c #18472C", +"C c #135226", +"Z c #125524", +"A c #314F3D", +"S c #487E05", +"D c #7A7F07", +"F c #425F39", +"G c #4A683A", +"H c #2A4557", +"J c #116B5D", +"K c #0B7B57", +"L c #0A7D55", +"P c #097F54", +"I c #0A7E55", +"U c #0A7C57", +"Y c #0B7C57", +"T c #0C7759", +"R c #0D775A", +"E c #0F735E", +"W c #0B7B58", +"Q c #0C7959", +"! c #195E6E", +"~ c #1E5377", +"^ c #1C5774", +"/ c #1D5476", +"( c #1D5576", +") c #1B5972", +"_ c #1A5C70", +"` c #225069", +"' c #204E7B", +"] c #146767", +"[ c #126C63", +"{ c #116E62", +"} c #136A65", +"| c #146966", +" . c #17636B", +".. c #17626C", +"X. c #18606D", +"o. c #850101", +"O. c #860101", +"+. c #8B0101", +"@. c #8D0101", +"#. c #8E0101", +"$. c #920101", +"%. c #940101", +"&. c #9B0000", +"*. c #9F0000", +"=. c #8E1600", +"-. c #A10000", +";. c #A30000", +":. c #A80000", +">. c #AE0000", +",. c #B50000", +"<. c #BA0000", +"1. c #BC0000", +"2. c #BE0000", +"3. c #BF0600", +"4. c #C20000", +"5. c #C40000", +"6. c #C30500", +"7. c #C80000", +"8. c #CB0000", +"9. c #CF0000", +"0. c #D00000", +"q. c #D30000", +"w. c #4F8706", +"e. c #518906", +"r. c #558F06", +"t. c #569006", +"y. c #5B9607", +"u. c #5D9A07", +"i. c #66A508", +"p. c #67A608", +"a. c #6AAA08", +"s. c #72B509", +"d. c #75B909", +"f. c #77BB09", +"g. c #7CC20A", +"h. c #7EC40A", +"j. c #7FC60A", +"k. c #018F47", +"l. c #05874D", +"z. c #06854F", +"x. c #05874E", +"c. c #06864F", +"v. c #038B4B", +"b. c #048A4B", +"n. c #038C49", +"m. c #028D49", +"M. c #038D49", +"N. c #028E48", +"B. c #028F48", +"V. c #038C4A", +"C. c #04894C", +"Z. c #05884D", +"A. c #009145", +"S. c #009245", +"D. c #019046", +"F. c #009146", +"G. c #019146", +"H. c #019047", +"J. c #078351", +"K. c #078450", +"L. c #068550", +"P. c #088152", +"I. c #098053", +"U. c #088252", +"Y. c #718865", +"T. c #85CD0A", +"R. c #86CF0A", +"E. c #89D20B", +"W. c #8AD40B", +"Q. c #8CD60B", +"!. c #8DD80B", +"~. c #2C3288", +"^. c #2E3192", +"/. c #0027B5", +"(. c #032AB6", +"). c #062CB7", +"_. c #0F34B9", +"`. c #1E40BE", +"'. c #2143BF", +"]. c #2D4DC2", +"[. c #3655C5", +"{. c #3957C6", +"}. c #425FC8", +"|. c #4561C9", +" X c #546ECD", +".X c #637BD2", +"XX c #6C82D4", +"oX c #82958F", +"OX c #909B9E", +"+X c #90A286", +"@X c #8F91C5", +"#X c #8799DC", +"$X c #8D9EDE", +"%X c #90A1DF", +"&X c #A6AFC7", +"*X c #A6A7D1", +"=X c #99A9E1", +"-X c #ABB8E7", +";X c #B7C2EA", +":X c #C6CFEE", +">X c #CCD4F0", +",X c #D2D9F2", +" ! .| { E R K P U.0X0X0X0X0X0XH.0X0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.: _ ..] [ 0X0X0XL I.0X0X0X0X0XN.k.0X0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.= ) ! 0X0X0X0X0XU P 0X0X0X0X0XN.B.0X0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.$ ^ _ 0X0X0X0X0XW 0X0X0X0X0X0Xm.N.0X0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.% N V 0X0X0X0X0XQ 0X0X0X0X0X0Xn.0X0X0X0X0X0X", +"a #.q.q.q.q.q.q.q.2.& 0X0X0X0XT 0X0XU.z.x.b.V.m.B.H.0X0X0X", +"0X#.q.q.q.q.q.q.q.2.; p.z B J C Z I P.K.x.C.v.m.N.0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.t !.E.w.s X . 0X0X0XZ.0X0X0X0X0X0X0X", +"0X#.q.q.q.q.q.q.q.2.i !.!.!.g.n y.z 0X0X0Xl.0X0X0X0X0X0X0X", +"0X$ $ $ $ $ $ $ $ u D !.!.!.!.!.i.m Q.t. 0XL.x.0X0X0X$ $ 0X0X", +"0X0X0X0X0X^.~. d e.E.!.!.!.!.!.!.!.!.R.f - r * 1 9 $.:.2.6 0X", +"0X0X0X^.^.^.^.@ x a.!.!.!.!.!.!.!.!.S 0 >.5.q.q.q.q.q.4 0X", +"0X0X0X0X0X*X@X0XOXF g m j.!.!.!.!.!.!.h.. 3.q.q.q.q.q.q.3 0X", +"0X0X0X9X9X9X9X9X9X9X+Xv O d r.W.!.!.!.!.!.M p q.q.q.q.q.q.< 0X", +"0X0X9X7X$X{.(.`. X,X9X&XA b !.!.!.!.!.!.s. q q.q.q.q.q.9.$ 0X", +"0X9X4X]./././././.).#X9XY.c f.T.d.d.d.u.u.u.l 6.q.q.q.q.7.$ 0X", +"9X8X[././././././././.;X3XG e q.q.q.q.q.4.$ 0X", +"9X=X/././././././././.'.9XoXk o h j + w y y =.q.q.q.q.q.q.1.$ 0X", +"9X X/./././././././././.1X9X0X' / H 8 q.q.q.q.q.q.q.q.q.q.,.$ 0X", +"9X|././././././././././.>X9X0X0X0X` 2 ;.0.q.q.q.q.q.q.q.q.>.$ 0X", +"9XXX/././././././././.(.5X9X0X0X0X( 0X$ 4 >.q.q.q.q.q.q.q.:.$ 0X", +"9X +#include + +// Mitk +#include +#include +#include +#include "mitkImageMappingHelper.h" +#include "mitkMAPRegistrationWrapper.h" +#include "mitkMatchPointPropertyTags.h" +#include "mitkRegistrationHelper.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// Qmitk +#include "QmitkMatchPointMapper.h" + +// Qt +#include +#include +#include +#include + +const std::string QmitkMatchPointMapper::VIEW_ID = "org.mitk.views.matchpoint.mapper"; + +QmitkMatchPointMapper::QmitkMatchPointMapper() + : m_Parent(NULL), m_preparedForBinaryInput(false) +{ +} + +void QmitkMatchPointMapper::SetFocus() +{ + //m_Controls.buttonPerformImageProcessing->setFocus(); +} + +void QmitkMatchPointMapper::CreateConnections() +{ + // show first page + m_Controls.m_tabs->setCurrentIndex(0); + + connect(m_Controls.m_pbLockReg, SIGNAL(clicked()), this, SLOT(OnLockRegButtonPushed())); + connect(m_Controls.m_pbLockInput, SIGNAL(clicked()), this, SLOT(OnLockInputButtonPushed())); + connect(m_Controls.m_pbLockRef, SIGNAL(clicked()), this, SLOT(OnLockReferenceButtonPushed())); + + connect(m_Controls.m_cbManualRef, SIGNAL(clicked()), this, SLOT(OnManualRefChecked())); + connect(m_Controls.m_cbLinkFactors, SIGNAL(clicked()), this, SLOT(OnLinkSampleFactorChecked())); + + connect(m_Controls.m_sbXFactor, SIGNAL(valueChanged(double)), this, SLOT(OnXFactorChanged(double))); + + connect(m_Controls.m_pbMap, SIGNAL(clicked()), this, SLOT(OnMapBtnPushed())); + connect(m_Controls.m_pbRefine, SIGNAL(clicked()), this, SLOT(OnRefineBtnPushed())); +} + +void QmitkMatchPointMapper::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); + + m_Controls.m_teLog->append(QString("") + msg + QString("")); +} + +void QmitkMatchPointMapper::CreateQtPartControl(QWidget* parent) +{ + // create GUI widgets from the Qt Designer's .ui file + m_Controls.setupUi(parent); + + m_Parent = parent; + + this->CreateConnections(); + this->CheckInputs(); + this->ConfigureProgressInfos(); + this->ConfigureMappingControls(); +} + +/** Method checks if the currently selected reg node has a direct kernel that +* can be decomposed in a rotation matrix and a offset. If this is true, true +* is returned. In all other cases false is returned.*/ +bool QmitkMatchPointMapper::IsAbleToRefineGeometry() const +{ + bool result = false; + + if (this->m_spSelectedRegNode.IsNotNull()) + { + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast + (this->m_spSelectedRegNode->GetData()); + + //if the helper does not return null, we can refine the geometry. + result = mitk::MITKRegistrationHelper::getAffineMatrix(wrapper, false).IsNotNull(); + } + + return result; +} + +bool QmitkMatchPointMapper::IsBinaryInput() const +{ + mitk::NodePredicateDataType::Pointer isLabelSet = mitk::NodePredicateDataType::New("LabelSetImage"); + mitk::NodePredicateDataType::Pointer isImage = mitk::NodePredicateDataType::New("Image"); + mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); + mitk::NodePredicateAnd::Pointer isLegacyMask = mitk::NodePredicateAnd::New(isImage, isBinary); + + mitk::NodePredicateOr::Pointer maskPredicate = mitk::NodePredicateOr::New(isLegacyMask, isLabelSet); + + bool result = false; + + if(this->m_spSelectedInputNode.IsNotNull()) + { + result = maskPredicate->CheckNode(this->m_spSelectedInputNode); + } + + return result; +} + +bool QmitkMatchPointMapper::IsPointSetInput() const +{ + bool result = false; + + if (this->m_spSelectedInputNode.IsNotNull()) + { + result = dynamic_cast(this->m_spSelectedInputNode->GetData()) != NULL; + } + + return result; +} + +mitk::DataNode::Pointer QmitkMatchPointMapper::GetSelectedRegNode() +{ + mitk::DataNode::Pointer spResult = NULL; + + typedef QList NodeListType; + + NodeListType nodes = this->GetDataManagerSelection(); + + for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) + { + if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + spResult = *pos; + break; + } + } + + return spResult; +} + + +QList QmitkMatchPointMapper::GetSelectedDataNodes() +{ + typedef QList NodeListType; + + NodeListType nodes = this->GetDataManagerSelection(); + NodeListType result; + + for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) + { + if (!mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + result.push_back(*pos); + } + } + + return result; +} + +mitk::DataNode::Pointer QmitkMatchPointMapper::GetAutoRefNodeByReg() +{ + mitk::DataNode::Pointer spResult = NULL; + + if (this->m_spSelectedRegNode.IsNotNull()) + { + std::string nodeName; + mitk::BaseProperty* uidProp = m_spSelectedRegNode->GetProperty(mitk::nodeProp_RegAlgTargetData); + + if (uidProp) + { + //search for the target node + mitk::NodePredicateProperty::Pointer predicate = mitk::NodePredicateProperty::New(mitk::nodeProp_UID, + uidProp); + spResult = this->GetDataStorage()->GetNode(predicate); + } + } + if (spResult.IsNull() && this->m_spSelectedInputNode.IsNotNull()) + { + //no really reference is available -> use the input as reference + spResult = this->m_spSelectedInputNode; + m_Controls.m_teLog->append( + QString("Cannot determine reference automatically. Use input image as reference.")); + } + + return spResult; +} + +void QmitkMatchPointMapper::CheckInputs() +{ + mitk::DataNode::Pointer regNode = this->GetSelectedRegNode(); + + QList dataNodes = this->GetSelectedDataNodes(); + + //first set the internal nodes according to selection + if (!m_Controls.m_pbLockReg->isChecked()) + { + this->m_spSelectedRegNode = regNode; + } + + if (!m_Controls.m_pbLockInput->isChecked()) + { + mitk::DataNode::Pointer inputNode = NULL; + + if (dataNodes.size() > 0) + { + inputNode = dataNodes[0]; + } + + this->m_spSelectedInputNode = inputNode; + } + + if (!(m_Controls.m_cbManualRef->isChecked())) + { + this->m_spSelectedRefNode = this->GetAutoRefNodeByReg(); + } + else + { + if (!m_Controls.m_pbLockRef->isChecked()) + { + mitk::DataNode::Pointer refNode = NULL; + + int relevantIndex = 1; + + if (m_Controls.m_pbLockInput->isChecked()) + { + //the input is locked thus use the first selected data node + relevantIndex = 0; + } + + if (dataNodes.size() > relevantIndex) + { + refNode = dataNodes[relevantIndex]; + } + + this->m_spSelectedRefNode = refNode; + } + } + + //second, check validity of the selected nodes + this->CheckNodesValidity(this->m_ValidReg, this->m_ValidInput, this->m_ValidRef); + + //third, configure widgets + if (this->m_spSelectedRegNode.IsNull()) + { + m_Controls.m_lbRegistrationName->setText( + QString("no registration selected!")); + } + else + { + if (this->m_ValidReg) + { + m_Controls.m_lbRegistrationName->setText(QString::fromStdString( + this->m_spSelectedRegNode->GetName())); + } + else + { + m_Controls.m_lbRegistrationName->setText(QString("") + QString::fromStdString( + this->m_spSelectedRegNode->GetName()) + QString("")); + } + } + + if (this->m_spSelectedInputNode.IsNull()) + { + m_Controls.m_lbInputName->setText(QString("no input selected!")); + } + else + { + if (this->m_ValidInput) + { + m_Controls.m_lbInputName->setText(QString::fromStdString(this->m_spSelectedInputNode->GetName())); + } + else + { + m_Controls.m_lbInputName->setText(QString("") + QString::fromStdString( + this->m_spSelectedInputNode->GetName()) + QString("")); + } + + } + + if (this->m_spSelectedRefNode.IsNull()) + { + if (this->m_ValidRef) + { + m_Controls.m_lbReferenceName->setText(QString("input needs no reference needed")); + } + else + { + m_Controls.m_lbReferenceName->setText(QString("no reference selected!")); + } + } + else + { + if (this->m_ValidRef) + { + m_Controls.m_lbReferenceName->setText(QString::fromStdString(this->m_spSelectedRefNode->GetName())); + + if (this->m_spSelectedRefNode->GetData() + && this->m_spSelectedRefNode->GetData()->GetTimeSteps() > 1) + { + m_Controls.m_teLog->append( + QString("Selected reference image has multiple time steps. Only geometry of time step 1 is used as reference.")); + } + } + else + { + m_Controls.m_lbReferenceName->setText(QString("") + QString::fromStdString( + this->m_spSelectedRefNode->GetName()) + QString("")); + } + } + + this->m_Controls.m_pbLockInput->setEnabled(this->m_spSelectedInputNode.IsNotNull()); + this->m_Controls.m_pbLockReg->setEnabled(this->m_spSelectedRegNode.IsNotNull()); + this->m_Controls.m_pbLockRef->setEnabled(this->m_spSelectedRefNode.IsNotNull()); +} + + +void QmitkMatchPointMapper::CheckNodesValidity(bool& validReg, bool& validInput, bool& validRef) +{ + validReg = this->m_spSelectedRegNode.IsNotNull(); + validInput = this->m_spSelectedInputNode.IsNotNull(); + validRef = this->m_spSelectedRefNode.IsNotNull(); + + if (this->m_spSelectedRegNode.IsNotNull()) + { + if (this->m_spSelectedInputNode.IsNotNull()) + { + validInput = false; + + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast < const mitk::MAPRegistrationWrapper* > + (m_spSelectedRegNode->GetData()); + mitk::Image* inputImage = dynamic_cast(m_spSelectedInputNode->GetData()); + + if (inputImage && wrapper) + { + if (inputImage->GetDimension() - 1 == wrapper->GetMovingDimensions() + && inputImage->GetTimeSteps() > 1) + { + //images has multiple time steps and a time step has the correct dimensionality + validInput = true; + } + + if (inputImage->GetDimension() == wrapper->GetMovingDimensions()) + { + validInput = true; + } + } + + if (this->IsPointSetInput() && wrapper) + { + if (wrapper->GetMovingDimensions() == 3) + { + validInput = true; + } + } + } + + if (this->m_spSelectedRefNode.IsNotNull()) + { + validRef = false; + + const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast < const mitk::MAPRegistrationWrapper* > + (m_spSelectedRegNode->GetData()); + mitk::BaseGeometry* geometry = NULL; + + if (m_spSelectedRefNode->GetData()) + { + geometry = m_spSelectedRefNode->GetData()->GetGeometry(); + } + + if (geometry && wrapper) + { + if (wrapper->GetTargetDimensions() == 3) + { + validRef = true; + } + else if (wrapper->GetTargetDimensions() == 2) + { + mitk::BaseGeometry::BoundsArrayType bounds = geometry->GetBounds(); + + if (bounds[4] != 0 || bounds[5] != 0) + { + //array "bounds" is constructed as [min Dim1, max Dim1, min Dim2, max Dim2, min Dim3, max Dim3] + //therfore [4] and [5] must be 0 + + validRef = true; + } + + } + } + } + else if (this->IsPointSetInput()) + { + validRef = true; + } + } +} + +void QmitkMatchPointMapper::ConfigureMappingControls() +{ + this->m_Controls.m_pbMap->setEnabled(this->m_ValidInput && this->m_ValidRef && (this->m_ValidReg || this->m_spSelectedRegNode.IsNull())); + this->m_Controls.m_pbRefine->setEnabled(this->m_ValidInput && this->m_ValidReg + && this->IsAbleToRefineGeometry() && !this->IsPointSetInput()); + this->m_Controls.m_pbLockRef->setEnabled(this->m_Controls.m_cbManualRef->isChecked()); + this->m_Controls.m_lbReferenceName->setEnabled(this->m_Controls.m_cbManualRef->isChecked()); + + if (this->m_ValidInput && this->m_ValidReg) + { + this->m_Controls.m_leMappedName->setText(tr("mapped_by_") + QString::fromStdString( + m_spSelectedRegNode->GetName())); + } + else + { + this->m_Controls.m_leMappedName->setText(tr("mappedData")); + } + + if (this->IsBinaryInput() != this->m_preparedForBinaryInput) + { + if (this->IsBinaryInput()) + { + m_Controls.m_teLog->append( + QString("Binary input (mask) detected. Preparing for mask mapping (default interpolation: nearest neigbour; padding value: 0)")); + + this->m_Controls.m_comboInterpolator->setCurrentIndex(0); + this->m_Controls.m_sbErrorValue->setValue(0); + this->m_Controls.m_sbPaddingValue->setValue(0); + } + else + { + this->m_Controls.m_comboInterpolator->setCurrentIndex(1); + } + + this->m_preparedForBinaryInput = this->IsBinaryInput(); + } + + OnLinkSampleFactorChecked(); +} + +void QmitkMatchPointMapper::ConfigureProgressInfos() +{ + +} + +void QmitkMatchPointMapper::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes) +{ + this->CheckInputs(); + this->ConfigureMappingControls(); +} + +void QmitkMatchPointMapper::OnLockRegButtonPushed() +{ + if (this->m_Controls.m_pbLockReg->isChecked()) + { + if (this->m_spSelectedRegNode.IsNotNull()) + { + this->m_spSelectedRegNode->SetSelected(false); + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureMappingControls(); +} + +void QmitkMatchPointMapper::OnLockInputButtonPushed() +{ + if (this->m_Controls.m_pbLockInput->isChecked()) + { + if (this->m_spSelectedInputNode.IsNotNull()) + { + this->m_spSelectedInputNode->SetSelected(false); + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureMappingControls(); +} + +void QmitkMatchPointMapper::OnLockReferenceButtonPushed() +{ + if (this->m_Controls.m_pbLockRef->isChecked()) + { + if (this->m_spSelectedRefNode.IsNotNull()) + { + this->m_spSelectedRefNode->SetSelected(false); + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureMappingControls(); +} + +void QmitkMatchPointMapper::OnManualRefChecked() +{ + this->CheckInputs(); + this->ConfigureMappingControls(); +} + +void QmitkMatchPointMapper::OnLinkSampleFactorChecked() +{ + this->m_Controls.m_sbYFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); + this->m_Controls.m_sbZFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); + + if (m_Controls.m_cbLinkFactors->isChecked()) + { + this->m_Controls.m_sbYFactor->setValue(this->m_Controls.m_sbXFactor->value()); + this->m_Controls.m_sbZFactor->setValue(this->m_Controls.m_sbXFactor->value()); + } +} + + +void QmitkMatchPointMapper::OnMapBtnPushed() +{ + SpawnMappingJob(); +} + +void QmitkMatchPointMapper::OnRefineBtnPushed() +{ + SpawnMappingJob(true); +} + +void QmitkMatchPointMapper::SpawnMappingJob(bool doGeometryRefinement) +{ + if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) + { + this->m_Controls.m_teLog->clear(); + } + + ///////////////////////// + //create job and put it into the thread pool + QmitkMappingJob* pJob = new QmitkMappingJob(); + pJob->setAutoDelete(true); + + pJob->m_spInputData = this->m_spSelectedInputNode->GetData(); + pJob->m_InputNodeUID = mitk::EnsureUID(this->m_spSelectedInputNode); + pJob->m_doGeometryRefinement = doGeometryRefinement; + + pJob->m_spRegNode = m_spSelectedRegNode; + if (m_spSelectedRegNode.IsNull()) + { + pJob->m_spRegNode = mitk::DataNode::New(); + pJob->m_spRegNode->SetData(mitk::GenerateIdentityRegistration3D().GetPointer()); + pJob->m_spRegNode->SetName("Auto_Generated_Identity_Transform"); + m_Controls.m_teLog->append( + QString("No registration selected. Preforming mapping with identity transform")); + } + + if (!doGeometryRefinement) + { + pJob->m_spRefGeometry = m_spSelectedRefNode->GetData()->GetGeometry()->Clone().GetPointer(); + + //check for super/sub sampling + if (m_Controls.m_groupActivateSampling->isChecked()) + { + //change the pixel count and spacing of the geometry + mitk::BaseGeometry::BoundsArrayType geoBounds = pJob->m_spRefGeometry->GetBounds(); + mitk::Vector3D geoSpacing = pJob->m_spRefGeometry->GetSpacing(); + + geoSpacing[0] = geoSpacing[0] / m_Controls.m_sbXFactor->value(); + geoSpacing[1] = geoSpacing[1] / m_Controls.m_sbYFactor->value(); + geoSpacing[2] = geoSpacing[2] / m_Controls.m_sbZFactor->value(); + + geoBounds[1] = geoBounds[1] * m_Controls.m_sbXFactor->value(); + geoBounds[3] = geoBounds[3] * m_Controls.m_sbYFactor->value(); + geoBounds[5] = geoBounds[5] * m_Controls.m_sbZFactor->value(); + + pJob->m_spRefGeometry->SetBounds(geoBounds); + pJob->m_spRefGeometry->SetSpacing(geoSpacing); + } + } + + pJob->m_MappedName = m_Controls.m_leMappedName->text().toStdString(); + pJob->m_allowUndefPixels = m_Controls.m_groupAllowUndefPixels->isChecked(); + pJob->m_paddingValue = m_Controls.m_sbPaddingValue->value(); + pJob->m_allowUnregPixels = m_Controls.m_groupAllowUnregPixels->isChecked(); + pJob->m_errorValue = m_Controls.m_sbErrorValue->value(); + pJob->m_InterpolatorLabel = m_Controls.m_comboInterpolator->currentText().toStdString(); + + switch (m_Controls.m_comboInterpolator->currentIndex()) + { + case 0: + pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::NearestNeighbor; + break; + + case 1: + pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; + break; + + case 2: + pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::BSpline_3; + break; + + case 3: + pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Hamming; + break; + + case 4: + pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Welch; + break; + } + + connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); + connect(pJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, + SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), + Qt::BlockingQueuedConnection); + connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnMappingInfo(QString))); + + m_Controls.m_teLog->append(QString("Started mapping job. Name: ") + + m_Controls.m_leMappedName->text() + QString("")); + + QThreadPool* threadPool = QThreadPool::globalInstance(); + threadPool->start(pJob); +} + + + +void QmitkMatchPointMapper::OnMapJobError(QString err) +{ + Error(err); +}; + +void QmitkMatchPointMapper::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, + const QmitkMappingJob* job) +{ + m_Controls.m_teLog->append(QString("Mapped entity stored. Name: ") + + QString::fromStdString(job->m_MappedName) + QString("")); + + mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, + spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputNodeUID, + job->m_doGeometryRefinement, job->m_InterpolatorLabel); + this->GetDataStorage()->Add(spMappedNode); + this->GetRenderWindowPart()->RequestUpdate(); + + this->CheckInputs(); + this->ConfigureMappingControls(); +}; + +void QmitkMatchPointMapper::OnMappingInfo(QString info) +{ + m_Controls.m_teLog->append(QString("") + info + QString("")); +}; + +void QmitkMatchPointMapper::OnXFactorChanged(double d) +{ + if (m_Controls.m_cbLinkFactors->isChecked()) + { + this->m_Controls.m_sbYFactor->setValue(d); + this->m_Controls.m_sbZFactor->setValue(d); + } +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.h b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.h new file mode 100644 index 0000000000..2133b9a562 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.h @@ -0,0 +1,180 @@ +/*=================================================================== + +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 __Q_MITK_MATCHPOINT_MAPPER_H +#define __Q_MITK_MATCHPOINT_MAPPER_H + +#include + +#include + +#include + +#include "ui_QmitkMatchPointMapper.h" + +#include "QmitkMappingJob.h" + +// MatchPoint + + +/*! + \brief QmitkMatchPointMapper + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkFunctionality + \ingroup ${plugin_target}_internal + */ +class QmitkMatchPointMapper : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPointMapper) + + QmitkMatchPointMapper(); + + virtual void CreateQtPartControl(QWidget *parent); + + protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + /// \brief Called when the user clicks the GUI button + + void OnLockRegButtonPushed(); + void OnLockInputButtonPushed(); + void OnLockReferenceButtonPushed(); + void OnManualRefChecked(); + void OnLinkSampleFactorChecked(); + + void OnXFactorChanged(double d); + + void OnMapBtnPushed(); + void OnRefineBtnPushed(); + + void OnMapJobError(QString err); + void OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job); + void OnMappingInfo(QString info); + +protected: + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& nodes); + + Ui::MatchPointMapperControls m_Controls; + +private: + QWidget *m_Parent; + + void MapNStoreImage(QmitkMappingJob* job); + + void Error(QString msg); + + /** Method checks if the currently selected reg node has a direct kernel that + * can be decomposed in a rotation matrix and a offset. If this is true, true + * is returned. In all other cases false is returned.*/ + bool IsAbleToRefineGeometry() const; + + /** Method checks if the currently selected input is a binary image (property binary == true). + * If this is true, true is returned. In all other cases false is returned.*/ + bool IsBinaryInput() const; + + /** Method checks if the currently selected input is a point set. + * If this is true, true is returned. In all other cases false is returned.*/ + bool IsPointSetInput() const; + + /** Function returns the first data node containing a registration wrapper + * in the current selection of the data manager. If nothing is selected or + * no registration wrapper is selected it return NULL.*/ + mitk::DataNode::Pointer GetSelectedRegNode(); + + /** Methods returns a list of all nodes selected in the data manager that do + * NOT contain registration wrappers. The list may be empty if nothing is + * selected or no appropriate data node is selected.*/ + QList GetSelectedDataNodes(); + + /** If a registration node is set, this function determines the auto reference node. + * The auto reference node is the node of the target data used to determine the + * registration object or, if the first cannot be determined, the currently selected input + * node. + * @return Pointer to the reference node (target data of the registration algorithm run). + * Function may return NULL if the referenced node cannot be found or is not defined + * by the registration.*/ + mitk::DataNode::Pointer GetAutoRefNodeByReg(); + + /** + * Checks if appropriated nodes are selected in the data manager. If nodes are selected, + * they are stored m_spSelectedRegNode, m_spSelectedInputNode and m_spSelectedRefNode. + * They are also checked for vadility and stored in m_ValidInput,... . + * It also sets the info lables accordingly.*/ + void CheckInputs(); + + /** Methods checks the validity of the currently stored + * m_spSelectedRegNode, m_spSelectedInputNode and m_spSelectedRefNode. + * Results are returned via the parameters. Details of the evaluation are + * printed to the log widget.*/ + void CheckNodesValidity(bool& validReg, bool& validInput, bool& validRef); + + /** + * Updates the state of mapping control button regarding to selected + * input, registration and reference.*/ + void ConfigureMappingControls(); + + /** + * Configures the progress bars accoarding to the choosen algorithm. + */ + void ConfigureProgressInfos(); + + /** + * Used to generate, configure and execute a mapping job regarding the + * current settings. + * @param doGeometryRefinement Set true if only a geometry refinement should be done. + * Set to false if a mapping/resampling of the input should be done.*/ + void SpawnMappingJob(bool doGeometryRefinement = false); + + mitk::DataNode::Pointer m_spSelectedRegNode; + mitk::DataNode::Pointer m_spSelectedInputNode; + mitk::DataNode::Pointer m_spSelectedRefNode; + + /** boolean variable to control visibility of GUI elements*/ + bool m_ValidReg; + /** boolean variable to control visibility of GUI elements*/ + bool m_ValidInput; + /** boolean variable to control visibility of GUI elements*/ + bool m_ValidRef; + + /** used for the internal logic to indicate of the current settings + are set for mapping binary images (used by ConfigureMappingControls()).*/ + bool m_preparedForBinaryInput; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.ui b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.ui new file mode 100644 index 0000000000..104ce912b9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.ui @@ -0,0 +1,836 @@ + + + MatchPointMapperControls + + + + 0 + 0 + 392 + 816 + + + + + 5 + + + 5 + + + + + Selected registration: + + + + + + + 3 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Registration that should be used to map the moving image... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the selected registration for mapping + + + + + + + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_lock.png:/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + + + true + + + false + + + false + + + + + + + + + Input data (images or point sets): + + + + + + + 3 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Moving image that should be mapped... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the selected moving image to do not change anymore + + + + + + + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_lock.png:/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + + + true + + + false + + + + + + + + + Select reference manually instat of determined by registration... + + + Select reference image manually: + + + + + + + 3 + + + + + + 0 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Reference image that is used to determine the field of view mapped into... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the reference image + + + + + + + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + :/org.mitk.gui.qt.matchpoint.mapper/resources/icon_lock.png:/org.mitk.gui.qt.matchpoint.mapper/resources/icon_unlock.png + + + true + + + false + + + + + + + + + true + + + 0 + + + false + + + false + + + false + + + + Execution + + + + 5 + + + 5 + + + + + Mapped data name: + + + + + + + Name of the resulting mapped image + + + mappedImage + + + + + + + + + <html><head/><body><p>Starts the mapping of the input image with the current settings.</p></body></html> + + + Map + + + + + + + false + + + <html><head/><body><p>Applys the registration by refining the geometry of the data and not by resampling it. This option can only be selected if the chosen registration is 3D and can be decomposed in a rotation matrix and offset.</p></body></html> + + + Refine geometry + + + + + + + + + Log: + + + + + + + + 9 + + + + true + + + QTextEdit::NoWrap + + + true + + + + + + + Clear log on mapping start + + + + + + + + Settings + + + + 5 + + + 5 + + + + + + 0 + 0 + + + + + 50 + false + + + + <html><head/><body><p>Allows that pixels may not be defined in the mapped image because they are outside of the field of view of the used input image.</p><p>The pixels will be marked with the given padding value.</p><p>If unchecked the mapping will be aborted in a case of undefined pixels.</p></body></html> + + + Allow undefined pixels + + + false + + + true + + + + 5 + + + 9 + + + 5 + + + 9 + + + 5 + + + + + Padding value: + + + + + + + + 0 + 0 + + + + Pixel value that indicates pixels that are outside of the input image + + + -5000 + + + 5000 + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + <html><head/><body><p>Allows that pixels may not be registred because they are outside of the field of view of the used registration. The location in the correlated input image pixel(s) are therefore unkown. The pixels will be marked witrh the given error value.</p><p>If unchecked the mapping will be aborted in a case of unregistered pixels.</p></body></html> + + + Allow unregistred pixels + + + false + + + true + + + + 5 + + + 5 + + + 5 + + + + + Error value: + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Value of pixels that cannot be registered because of an unsufficient field of view of the selected registration instance.</p></body></html> + + + -5000 + + + 5000 + + + + + + + + + + + 0 + 0 + + + + Interpolator: + + + + + + + true + + + <html><head/><body><p>Interpolation function that should be used to map the pixel values from the input image into the result image.</p></body></html> + + + 1 + + + + Nearest Neighbor + + + + + Linear + + + + + BSpline (3rd order) + + + + + Windowed Sinc (Hamming) + + + + + Windowed Sinc (Welch) + + + + + + + + + 0 + 0 + + + + Activate super/sub sampling + + + true + + + false + + + + 5 + + + + + <html><head/><body><p>Check to ensure that x, y and z dimension use the same sampling factor.</p></body></html> + + + linked factors + + + true + + + + + + + + + + 0 + 0 + + + + x: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + <html><head/><body><p>Indicate the sampling factor to change the resolution.</p><p>2.0: doubled resolution; e.g. 100 pixels -&gt; 200 pixels and spacing 1 -&gt; spacing 0.5</p><p>0.5: half resolution; e.g. 100 pixels -&gt; 50 pixels and spacing 1 -&gt; spacing 2</p></body></html> + + + + + + + y: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + z: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 700 + + + + + + + + + + + + + + + 5 + + + 5 + + + true + + + true + + + true + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.cpp new file mode 100644 index 0000000000..46f4a5770d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.cpp @@ -0,0 +1,41 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "org_mitk_gui_qt_matchpoint_mapper_Activator.h" + +#include "QmitkMatchPointMapper.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_mapper_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_mapper_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPointMapper, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_mapper_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_mapper_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.h new file mode 100644 index 0000000000..b76bab2456 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/org_mitk_gui_qt_matchpoint_mapper_Activator.h @@ -0,0 +1,43 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef org_mitk_gui_qt_matchpoint_mapper_Activator_h +#define org_mitk_gui_qt_matchpoint_mapper_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_mapper_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_mapper") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_matchpoint_mapper_Activator + +#endif // org_mitk_gui_qt_matchpoint_mapper_Activator_h diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/CMakeLists.txt b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/CMakeLists.txt new file mode 100644 index 0000000000..57513f9e1a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/CMakeLists.txt @@ -0,0 +1,7 @@ +project(org_mitk_gui_qt_matchpoint_visualizer) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_MITK_GUI_QT_REGVIS_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt MitkMatchPointRegistration +) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox new file mode 100644 index 0000000000..4335a47bbc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/Manual.dox @@ -0,0 +1,23 @@ +/** +\page org_mitk_gui_qt_registration_visualizer The MatchPoint Registration Visualizer Plugin + +\imageMacro{map-icon-regvis.png, "Icon of the Registration Visualizer",3} + +\li \ref MAP_VIS_Introduction +\li \ref MAP_VIS_Contact +\li \ref MAP_VIS_Usage + +\section MAP_VIS_Introduction Introduction +This plugins is in development to offer the user a way to visualize MatchPoint registrations in an MITK scene. +Currently only a simple grid visualization is implemented.\n +\remark This is an experimental version and work in progress. So please excuse errors or usage issues and report them. This plugin will be improved and polished with the next releases. + +\section MAP_VIS_Contact Contact information +This plug-in is being developed by the SIDT group (Software development for Integrated Diagnostics +and Therapy) at the DKFZ (German Cancer Research Center). If you have any questions, need support, +find a bug or have a feature request, feel free to contact us at dipp@dkfz.de. + +\section MAP_VIS_Usage Usage +Oops. Documentation is missing and to be done. +*/ + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/map-icon-regvis.png b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/map-icon-regvis.png new file mode 100644 index 0000000000..af620f00ce Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/UserManual/map-icon-regvis.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..6ff84806d5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_gui_qt_mapper org.mitk.gui.qt.mapper + \ingroup MITKPlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_internal Internal + \ingroup org_mitk + + \brief This subcategory includes the internal classes of the org.mitk plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/files.cmake b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/files.cmake new file mode 100644 index 0000000000..96ce8a2852 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/files.cmake @@ -0,0 +1,45 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_matchpoint_visualizer_Activator.cpp + QmitkMatchPointRegistrationVisualizer.cpp +) + +set(UI_FILES + src/internal/QmitkMatchPointRegistrationVisualizer.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.h + src/internal/QmitkMatchPointRegistrationVisualizer.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + resources/icon.png + resources/icon_lock.png + resources/icon_unlock.png + plugin.xml +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/manifest_headers.cmake new file mode 100644 index 0000000000..4804af1214 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "MatchPoint Registration Visualizer") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager) diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/plugin.xml b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/plugin.xml new file mode 100644 index 0000000000..5248d2b270 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon.png b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon.png new file mode 100644 index 0000000000..af620f00ce Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_lock.png b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_lock.png new file mode 100644 index 0000000000..7ca3d301a9 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_lock.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_unlock.png b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_unlock.png new file mode 100644 index 0000000000..f6575c53af Binary files /dev/null and b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/icon_unlock.png differ diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/readme_icon.txt b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/readme_icon.txt new file mode 100644 index 0000000000..07e12fdc30 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/resources/readme_icon.txt @@ -0,0 +1,8 @@ +The icons icon_lock.png and icon_unlock.png are based on: + +Crystal Clear action exit.svg Image:Crystal Clear action lock1.png +Crystal Clear icon by Everaldo Coelho and YellowIcon. + +Distriubted over Wikimedia commons under LGPL. + +Thank you very much. diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp new file mode 100644 index 0000000000..ca795f7fc9 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.cpp @@ -0,0 +1,846 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_matchpoint_visualizer_Activator.h" + +// Blueberry +#include +#include + +// Mitk +#include +#include +#include +#include +#include "mitkRegVisDirectionProperty.h" +#include "mitkRegVisStyleProperty.h" +#include "mitkRegVisColorStyleProperty.h" +#include "mitkRegVisPropertyTags.h" +#include "mitkRegVisHelper.h" +#include "mitkMatchPointPropertyTags.h" +#include "mitkRegistrationHelper.h" + +// Qmitk +#include "QmitkMatchPointRegistrationVisualizer.h" + +// Qt +#include +#include + +const std::string QmitkMatchPointRegistrationVisualizer::VIEW_ID = +"org.mitk.views.matchpoint.visualizer"; + +QmitkMatchPointRegistrationVisualizer::QmitkMatchPointRegistrationVisualizer() + : m_Parent(NULL), m_internalUpdateGuard(false), m_spSelectedFOVRefNode(NULL), + m_spSelectedRegNode(NULL) +{ +} + +void QmitkMatchPointRegistrationVisualizer::SetFocus() +{ + //m_Controls->buttonPerformImageProcessing->setFocus(); +} + +void QmitkMatchPointRegistrationVisualizer::CreateConnections() +{ + // show first page + connect(m_Controls->m_pbLockReg, SIGNAL(clicked()), this, SLOT(OnLockRegButtonPushed())); + + connect(m_Controls->m_pbStyleGrid, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); + connect(m_Controls->m_pbStyleGlyph, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); + connect(m_Controls->m_pbStylePoints, SIGNAL(clicked()), this, SLOT(OnStyleButtonPushed())); + + connect(m_Controls->m_comboDirection, SIGNAL(currentIndexChanged(int)), this, + SLOT(OnDirectionChanged(int))); + connect(m_Controls->m_pbUpdateViz, SIGNAL(clicked()), this, SLOT(OnUpdateBtnPushed())); + + connect(m_Controls->m_pbUseFOVRef, SIGNAL(clicked()), this, SLOT(OnUseFOVRefBtnPushed())); + + connect(m_Controls->radioColorUni, SIGNAL(toggled(bool)), m_Controls->btnUniColor, + SLOT(setEnabled(bool))); + connect(m_Controls->radioColorVecMag, SIGNAL(toggled(bool)), m_Controls->groupColorCoding, + SLOT(setEnabled(bool))); + + connect(m_Controls->m_pbStyleGrid, SIGNAL(toggled(bool)), m_Controls->tabGrid, + SLOT(setEnabled(bool))); + + connect(m_Controls->cbVevMagInterlolate, SIGNAL(toggled(bool)), this, + SLOT(OnColorInterpolationChecked(bool))); +} + +void QmitkMatchPointRegistrationVisualizer::Error(QString msg) +{ + mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); + MITK_ERROR << msg.toStdString().c_str(); +} + +void QmitkMatchPointRegistrationVisualizer::CreateQtPartControl(QWidget* parent) +{ + m_Controls = new Ui::MatchPointRegVisControls; + + // create GUI widgets from the Qt Designer's .ui file + m_Controls->setupUi(parent); + + m_Parent = parent; + + this->m_Controls->btnVecMagColorSmall->setDisplayColorName(false); + this->m_Controls->btnVecMagColorMedium->setDisplayColorName(false); + this->m_Controls->btnVecMagColorLarge->setDisplayColorName(false); + this->m_Controls->btnVecMagColorNeg->setDisplayColorName(false); + this->m_Controls->btnUniColor->setDisplayColorName(false); + this->m_Controls->btnStartGridColor->setDisplayColorName(false); + + this->CreateConnections(); + + this->m_Controls->radioColorUni->setChecked(false); + this->m_Controls->radioColorVecMag->setChecked(true); + + this->CheckInputs(); + this->LoadStateFromNode(); + this->ConfigureVisualizationControls(); +} + +mitk::MAPRegistrationWrapper* QmitkMatchPointRegistrationVisualizer::GetCurrentRegistration() +{ + mitk::MAPRegistrationWrapper* result = NULL; + + if (this->m_spSelectedRegNode.IsNotNull()) + { + result = dynamic_cast(this->m_spSelectedRegNode->GetData()); + assert(result); + } + + return result; +} + +mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetSelectedRegNode() const +{ + mitk::DataNode::Pointer spResult = NULL; + + typedef QList NodeListType; + + NodeListType nodes = this->GetDataManagerSelection(); + + for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) + { + if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) + { + spResult = *pos; + break; + } + } + + return spResult; +} + +mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetRefNodeOfReg(bool target) const +{ + mitk::DataNode::Pointer spResult = NULL; + + if (this->m_spSelectedRegNode.IsNotNull()) + { + std::string nodeName; + mitk::BaseProperty* uidProp; + + if (target) + { + uidProp = m_spSelectedRegNode->GetProperty(mitk::nodeProp_RegAlgTargetData); + } + else + { + uidProp = m_spSelectedRegNode->GetProperty(mitk::nodeProp_RegAlgMovingData); + } + + if (uidProp) + { + //search for the target node + mitk::NodePredicateProperty::Pointer predicate = mitk::NodePredicateProperty::New(mitk::nodeProp_UID, + uidProp); + spResult = this->GetDataStorage()->GetNode(predicate); + } + } + + return spResult; +} + +mitk::DataNode::Pointer QmitkMatchPointRegistrationVisualizer::GetSelectedDataNode() +{ + typedef QList NodeListType; + + NodeListType nodes = this->GetDataManagerSelection(); + mitk::DataNode::Pointer result; + + for (NodeListType::iterator pos = nodes.begin(); pos != nodes.end(); ++pos) + { + if (!mitk::MITKRegistrationHelper::IsRegNode(*pos) && (*pos)->GetData() + && (*pos)->GetData()->GetGeometry()) + { + result = *pos; + break; + } + } + + return result; +} + +void QmitkMatchPointRegistrationVisualizer::CheckInputs() +{ + mitk::DataNode::Pointer regNode = this->GetSelectedRegNode(); + + if (!m_Controls->m_pbLockReg->isChecked()) + { + this->m_spSelectedRegNode = regNode; + } + + this->InitRegNode(); + + mitk::DataNode::Pointer fovNode = this->GetSelectedDataNode(); + + if (!m_Controls->m_pbLockFOVRef->isChecked()) + { + this->m_spSelectedFOVRefNode = fovNode; + } +} + +void QmitkMatchPointRegistrationVisualizer::ConfigureVisualizationControls() +{ + if (!m_internalUpdateGuard) + { + m_internalUpdateGuard = true; + m_Controls->groupViz->setVisible(this->m_spSelectedRegNode.IsNotNull()); + + m_Controls->m_pbUpdateViz->setEnabled(this->m_spSelectedRegNode.IsNotNull()); + m_Controls->m_boxSettings->setEnabled(this->m_spSelectedRegNode.IsNotNull()); + m_Controls->m_boxStyles->setEnabled(this->m_spSelectedRegNode.IsNotNull()); + + this->ActualizeRegInfo(this->GetCurrentRegistration()); + + if (this->m_spSelectedRegNode.IsNull()) + { + m_Controls->m_lbRegistrationName->setText( + QString("no registration selected!")); + } + else + { + m_Controls->m_lbRegistrationName->setText(QString::fromStdString( + this->m_spSelectedRegNode->GetName())); + } + + this->m_Controls->m_pbLockReg->setEnabled(this->m_spSelectedRegNode.IsNotNull()); + this->m_Controls->m_pbUseFOVRef->setEnabled(this->m_spSelectedRegNode.IsNotNull() + && this->m_spSelectedFOVRefNode.IsNotNull()); + this->m_Controls->m_checkUseRefSize->setEnabled(this->m_spSelectedRegNode.IsNotNull() + && this->m_spSelectedFOVRefNode.IsNotNull()); + this->m_Controls->m_checkUseRefOrigin->setEnabled(this->m_spSelectedRegNode.IsNotNull() + && this->m_spSelectedFOVRefNode.IsNotNull()); + this->m_Controls->m_checkUseRefSpacing->setEnabled(this->m_spSelectedRegNode.IsNotNull() + && this->m_spSelectedFOVRefNode.IsNotNull()); + + this->m_Controls->m_pbLockFOVRef->setEnabled(this->m_spSelectedFOVRefNode.IsNotNull()); + + if (this->m_spSelectedFOVRefNode.IsNull()) + { + m_Controls->m_lbFOVRef->setText(QString("no valid reference selected!")); + } + else + { + m_Controls->m_lbFOVRef->setText(QString::fromStdString(this->m_spSelectedFOVRefNode->GetName())); + } + + m_internalUpdateGuard = false; + } +} + +void QmitkMatchPointRegistrationVisualizer::StoreStateInNode() +{ + if (this->m_spSelectedRegNode.IsNotNull()) + { + //general + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisDirection, + mitk::RegVisDirectionProperty::New(this->m_Controls->m_comboDirection->currentIndex())); + + this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGrid, + this->m_Controls->m_pbStyleGrid->isChecked()); + this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGlyph, + this->m_Controls->m_pbStyleGlyph->isChecked()); + this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisPoints, + this->m_Controls->m_pbStylePoints->isChecked()); + + //Visualization + if (this->m_Controls->radioColorUni->isChecked()) + { + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisColorStyle, + mitk::RegVisColorStyleProperty::New(0)); + } + else + { + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisColorStyle, + mitk::RegVisColorStyleProperty::New(1)); + } + + float tmpColor[3]; + + tmpColor[0] = this->m_Controls->btnUniColor->color().redF(); + tmpColor[1] = this->m_Controls->btnUniColor->color().greenF(); + tmpColor[2] = this->m_Controls->btnUniColor->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorUni, + mitk::ColorProperty::New(tmpColor), NULL, true); + + tmpColor[0] = this->m_Controls->btnVecMagColorNeg->color().redF(); + tmpColor[1] = this->m_Controls->btnVecMagColorNeg->color().greenF(); + tmpColor[2] = this->m_Controls->btnVecMagColorNeg->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor1Value, + mitk::ColorProperty::New(tmpColor), NULL, true); + + tmpColor[0] = this->m_Controls->btnVecMagColorSmall->color().redF(); + tmpColor[1] = this->m_Controls->btnVecMagColorSmall->color().greenF(); + tmpColor[2] = this->m_Controls->btnVecMagColorSmall->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Value, + mitk::ColorProperty::New(tmpColor), NULL, true); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Magnitude, + mitk::DoubleProperty::New(this->m_Controls->sbVecMagSmall->value()), NULL, true); + + tmpColor[0] = this->m_Controls->btnVecMagColorMedium->color().redF(); + tmpColor[1] = this->m_Controls->btnVecMagColorMedium->color().greenF(); + tmpColor[2] = this->m_Controls->btnVecMagColorMedium->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Value, + mitk::ColorProperty::New(tmpColor), NULL, true); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Magnitude, + mitk::DoubleProperty::New(this->m_Controls->sbVecMagMedium->value()), NULL, true); + + tmpColor[0] = this->m_Controls->btnVecMagColorLarge->color().redF(); + tmpColor[1] = this->m_Controls->btnVecMagColorLarge->color().greenF(); + tmpColor[2] = this->m_Controls->btnVecMagColorLarge->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Value, + mitk::ColorProperty::New(tmpColor), NULL, true); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Magnitude, + mitk::DoubleProperty::New(this->m_Controls->sbVecMagLarge->value()), NULL, true); + + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorInterpolate, + mitk::BoolProperty::New(this->m_Controls->cbVevMagInterlolate->isChecked()), NULL, true); + + //Grid Settings + this->m_spSelectedRegNode->SetIntProperty(mitk::nodeProp_RegVisGridFrequence, + this->m_Controls->m_sbGridFrequency->value()); + this->m_spSelectedRegNode->SetBoolProperty(mitk::nodeProp_RegVisGridShowStart, + this->m_Controls->m_groupShowStartGrid->isChecked()); + tmpColor[0] = this->m_Controls->btnStartGridColor->color().redF(); + tmpColor[1] = this->m_Controls->btnStartGridColor->color().greenF(); + tmpColor[2] = this->m_Controls->btnStartGridColor->color().blueF(); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridStartColor, + mitk::ColorProperty::New(tmpColor), NULL, true); + + //FOV + mitk::Vector3D value; + value[0] = this->m_Controls->m_sbFOVSizeX->value(); + value[1] = this->m_Controls->m_sbFOVSizeY->value(); + value[2] = this->m_Controls->m_sbFOVSizeZ->value(); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVSize, + mitk::Vector3DProperty::New(value)); + + value[0] = this->m_Controls->m_sbGridSpX->value(); + value[1] = this->m_Controls->m_sbGridSpY->value(); + value[2] = this->m_Controls->m_sbGridSpZ->value(); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVSpacing, + mitk::Vector3DProperty::New(value)); + + mitk::Point3D origin; + origin[0] = this->m_Controls->m_sbFOVOriginX->value(); + origin[1] = this->m_Controls->m_sbFOVOriginY->value(); + origin[2] = this->m_Controls->m_sbFOVOriginZ->value(); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrigin, + mitk::Point3dProperty::New(origin)); + + mitk::Vector3D orientationRow1; + mitk::Vector3D orientationRow2; + mitk::Vector3D orientationRow3; + orientationRow1.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(0)); + orientationRow2.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(1)); + orientationRow3.SetVnlVector(m_FOVRefOrientation.GetVnlMatrix().get_row(2)); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation1, + mitk::Vector3DProperty::New(orientationRow1)); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation2, + mitk::Vector3DProperty::New(orientationRow2)); + this->m_spSelectedRegNode->SetProperty(mitk::nodeProp_RegVisFOVOrientation3, + mitk::Vector3DProperty::New(orientationRow3)); + + } +} + +void QmitkMatchPointRegistrationVisualizer::LoadStateFromNode() +{ + if (this->m_spSelectedRegNode.IsNotNull()) + { + mitk::RegVisDirectionProperty* directionProp = NULL; + + if (this->m_spSelectedRegNode->GetProperty(directionProp, mitk::nodeProp_RegVisDirection)) + { + this->m_Controls->m_comboDirection->setCurrentIndex(directionProp->GetValueAsId()); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisDirection) + QString(" has not the assumed type.")); + } + + bool styleActive = false; + + if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGrid, styleActive)) + { + this->m_Controls->m_pbStyleGrid->setChecked(styleActive); + this->m_Controls->tabGrid->setEnabled(styleActive); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisGrid) + QString(" has not the assumed type.")); + } + + if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGlyph, styleActive)) + { + this->m_Controls->m_pbStyleGlyph->setChecked(styleActive); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisGlyph) + QString(" has not the assumed type.")); + } + + if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisPoints, styleActive)) + { + this->m_Controls->m_pbStylePoints->setChecked(styleActive); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisPoints) + QString(" has not the assumed type.")); + } + + /////////////////////////////////////////////////////// + //visualization + mitk::RegVisColorStyleProperty* colorStyleProp = NULL; + + if (this->m_spSelectedRegNode->GetProperty(colorStyleProp, mitk::nodeProp_RegVisColorStyle)) + { + this->m_Controls->radioColorUni->setChecked(colorStyleProp->GetValueAsId() == 0); + this->m_Controls->radioColorVecMag->setChecked(colorStyleProp->GetValueAsId() == 1); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisColorStyle) + QString(" has not the assumed type.")); + } + + QColor tmpColor; + float colorUni[3] = { 0.0, 0.0, 0.0 }; + this->m_spSelectedRegNode->GetColor(colorUni, NULL, mitk::nodeProp_RegVisColorUni); + tmpColor.setRgbF(colorUni[0], colorUni[1], colorUni[2]); + this->m_Controls->btnUniColor->setColor(tmpColor); + + float color1[3] = { 0.0, 0.0, 0.0 }; + this->m_spSelectedRegNode->GetColor(color1, NULL, mitk::nodeProp_RegVisColor1Value); + tmpColor.setRgbF(color1[0], color1[1], color1[2]); + this->m_Controls->btnVecMagColorNeg->setColor(tmpColor); + + float color2[3] = { 0.25, 0.25, 0.25 }; + this->m_spSelectedRegNode->GetColor(color2, NULL, mitk::nodeProp_RegVisColor2Value); + tmpColor.setRgbF(color2[0], color2[1], color2[2]); + this->m_Controls->btnVecMagColorSmall->setColor(tmpColor); + + float color3[3] = { 0.5, 0.5, 0.5 }; + this->m_spSelectedRegNode->GetColor(color3, NULL, mitk::nodeProp_RegVisColor3Value); + tmpColor.setRgbF(color3[0], color3[1], color3[2]); + this->m_Controls->btnVecMagColorMedium->setColor(tmpColor); + + float color4[3] = { 1.0, 1.0, 1.0 }; + this->m_spSelectedRegNode->GetColor(color4, NULL, mitk::nodeProp_RegVisColor4Value); + tmpColor.setRgbF(color4[0], color4[1], color4[2]); + this->m_Controls->btnVecMagColorLarge->setColor(tmpColor); + + double mag2 = 0; + this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor2Magnitude, mag2); + double mag3 = 0; + this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor3Magnitude, mag3); + double mag4 = 0; + this->m_spSelectedRegNode->GetPropertyValue(mitk::nodeProp_RegVisColor4Magnitude, mag4); + + bool interpolate = true; + this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisColorInterpolate, interpolate); + + this->m_Controls->sbVecMagSmall->setValue(mag2); + this->m_Controls->sbVecMagMedium->setValue(mag3); + this->m_Controls->sbVecMagLarge->setValue(mag4); + + this->m_Controls->cbVevMagInterlolate->setChecked(interpolate); + + /////////////////////////////////////////////////////// + //Grid general + bool showStart = false; + + if (this->m_spSelectedRegNode->GetBoolProperty(mitk::nodeProp_RegVisGridShowStart, showStart)) + { + this->m_Controls->m_groupShowStartGrid->setChecked(showStart); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisGridShowStart) + QString(" is not correctly defined.")); + } + + int gridFrequ = 5; + + if (this->m_spSelectedRegNode->GetIntProperty(mitk::nodeProp_RegVisGridFrequence, gridFrequ)) + { + this->m_Controls->m_sbGridFrequency->setValue(gridFrequ); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisGridFrequence) + QString(" is not correctly defined.")); + } + + float colorStart[3] = { 0.0, 0.0, 0.0 }; + this->m_spSelectedRegNode->GetColor(colorStart, NULL, mitk::nodeProp_RegVisGridStartColor); + tmpColor.setRgbF(colorStart[0], colorStart[1], colorStart[2]); + this->m_Controls->btnStartGridColor->setColor(tmpColor); + + /////////////////////////////////////////////////////// + //FOV + mitk::Vector3DProperty* valueProp = NULL; + + if (this->m_spSelectedRegNode->GetProperty(valueProp, mitk::nodeProp_RegVisFOVSize)) + { + this->m_Controls->m_sbFOVSizeX->setValue(valueProp->GetValue()[0]); + this->m_Controls->m_sbFOVSizeY->setValue(valueProp->GetValue()[1]); + this->m_Controls->m_sbFOVSizeZ->setValue(valueProp->GetValue()[2]); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisFOVSize) + QString(" is not correctly defined.")); + } + + if (this->m_spSelectedRegNode->GetProperty(valueProp, mitk::nodeProp_RegVisFOVSpacing)) + { + this->m_Controls->m_sbGridSpX->setValue(valueProp->GetValue()[0]); + this->m_Controls->m_sbGridSpY->setValue(valueProp->GetValue()[1]); + this->m_Controls->m_sbGridSpZ->setValue(valueProp->GetValue()[2]); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisFOVSpacing) + QString(" is not correctly defined.")); + } + + mitk::Point3dProperty* originProp = NULL; + + if (this->m_spSelectedRegNode->GetProperty(originProp, mitk::nodeProp_RegVisFOVOrigin)) + { + this->m_Controls->m_sbFOVOriginX->setValue(originProp->GetValue()[0]); + this->m_Controls->m_sbFOVOriginY->setValue(originProp->GetValue()[1]); + this->m_Controls->m_sbFOVOriginZ->setValue(originProp->GetValue()[2]); + } + else + { + this->Error(QString("Cannot configure plugin controlls correctly. Node property ") + QString( + mitk::nodeProp_RegVisFOVOrigin) + QString(" is not correctly defined.")); + } + + mitk::Vector3DProperty* orientationProp1; + mitk::Vector3DProperty* orientationProp2; + mitk::Vector3DProperty* orientationProp3; + + if (this->m_spSelectedRegNode->GetProperty(orientationProp1, mitk::nodeProp_RegVisFOVOrientation1) && + this->m_spSelectedRegNode->GetProperty(orientationProp2, mitk::nodeProp_RegVisFOVOrientation2) && + this->m_spSelectedRegNode->GetProperty(orientationProp3, mitk::nodeProp_RegVisFOVOrientation3)) + { + this->m_Controls->m_sbFOVOriginX->setValue(originProp->GetValue()[0]); + this->m_Controls->m_sbFOVOriginY->setValue(originProp->GetValue()[1]); + this->m_Controls->m_sbFOVOriginZ->setValue(originProp->GetValue()[2]); + m_FOVRefOrientation.GetVnlMatrix().set_row(0, orientationProp1->GetValue().GetVnlVector()); + m_FOVRefOrientation.GetVnlMatrix().set_row(1, orientationProp2->GetValue().GetVnlVector()); + m_FOVRefOrientation.GetVnlMatrix().set_row(2, orientationProp3->GetValue().GetVnlVector()); + } + else + { + m_FOVRefOrientation.SetIdentity(); + + this->Error(QString("Cannot configure plugin controlls correctly. One of the node propertiesy ") + + QString(mitk::nodeProp_RegVisFOVOrientation1) + QString(mitk::nodeProp_RegVisFOVOrientation2) + + QString(mitk::nodeProp_RegVisFOVOrientation3) + QString(" is not correctly defined.")); + } + + this->UpdateOrientationMatrixWidget(); + } +} + +void QmitkMatchPointRegistrationVisualizer::CheckAndSetDefaultFOVRef() +{ + //check if node has a default reference node. + mitk::DataNode::Pointer defaultRef = this->GetRefNodeOfReg( + this->m_Controls->m_comboDirection->currentIndex() == + 1); //direction value 1 = show inverse mapping -> we need the target image used for the registration. + + //if there is a default node and no m_spSelectedFOVRefNode is set -> set default node and transfer values + if (defaultRef.IsNotNull() && this->m_spSelectedFOVRefNode.IsNull() + && !(this->m_Controls->m_pbLockFOVRef->isDown())) + { + //there is a default ref and no ref lock -> select default ref and transfer its values + this->m_spSelectedFOVRefNode = defaultRef; + this->m_Controls->m_checkUseRefSize->setChecked(true); + this->m_Controls->m_checkUseRefOrigin->setChecked(true); + this->m_Controls->m_checkUseRefSpacing->setChecked(true); + this->m_Controls->m_checkUseRefOrientation->setChecked(true); + + //auto transfere values + this->OnUseFOVRefBtnPushed(); + } +} + +void QmitkMatchPointRegistrationVisualizer::OnSelectionChanged( + berry::IWorkbenchPart::Pointer /*source*/, + const QList& nodes) +{ + this->CheckInputs(); + this->LoadStateFromNode(); + this->CheckAndSetDefaultFOVRef(); + this->ConfigureVisualizationControls(); +} + +void QmitkMatchPointRegistrationVisualizer::ActualizeRegInfo(mitk::MAPRegistrationWrapper* + currentReg) +{ + std::stringstream descriptionString; + + m_Controls->m_teRegInfo->clear(); + + if (currentReg) + { + descriptionString << "Moving dimension: " << currentReg->GetMovingDimensions() << "
"; + descriptionString << "Target dimension: " << currentReg->GetTargetDimensions() << "
"; + descriptionString << "Limited moving representation: " << + currentReg->HasLimitedMovingRepresentation() << "
"; + descriptionString << "Limited target representation: " << + currentReg->HasLimitedTargetRepresentation() << "
"; + + mitk::MAPRegistrationWrapper::TagMapType tagMap = currentReg->GetTags(); + + descriptionString << "
Tags:
"; + + for (mitk::MAPRegistrationWrapper::TagMapType::const_iterator pos = tagMap.begin(); + pos != tagMap.end(); ++pos) + { + descriptionString << pos->first << " : " << pos->second << "
"; + } + } + else + { + descriptionString << "no registration selected!"; + } + + m_Controls->m_teRegInfo->insertHtml(QString::fromStdString(descriptionString.str())); + +} + +void QmitkMatchPointRegistrationVisualizer::OnDirectionChanged(int index) +{ + this->CheckAndSetDefaultFOVRef(); + this->ConfigureVisualizationControls(); +}; + +void QmitkMatchPointRegistrationVisualizer::OnLockRegButtonPushed() +{ + if (this->m_Controls->m_pbLockReg->isChecked()) + { + if (this->m_spSelectedRegNode.IsNotNull()) + { + this->m_spSelectedRegNode->SetSelected(false); + this->GetDataStorage()->Modified(); + } + } + + this->CheckInputs(); + this->ConfigureVisualizationControls(); +} + + +void QmitkMatchPointRegistrationVisualizer::OnUpdateBtnPushed() +{ + this->StoreStateInNode(); + + mitk::Geometry3D::Pointer gridDesc; + unsigned int gridFrequ = 5; + + mitk::GetGridGeometryFromNode(this->m_spSelectedRegNode, gridDesc, gridFrequ); + + this->GetCurrentRegistration()->SetGeometry(gridDesc); + mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll(); +} + +void QmitkMatchPointRegistrationVisualizer::OnStyleButtonPushed() +{ + +} + +void QmitkMatchPointRegistrationVisualizer::OnColorInterpolationChecked(bool checked) +{ + if (checked) + { + this->m_Controls->labelVecMagSmall->setText(QString("=")); + this->m_Controls->labelVecMagMedium->setText(QString("=")); + this->m_Controls->labelVecMagLarge->setText(QString("=")); + } + else + { + this->m_Controls->labelVecMagSmall->setText(QString(">")); + this->m_Controls->labelVecMagMedium->setText(QString(">")); + this->m_Controls->labelVecMagLarge->setText(QString(">")); + } +}; + +mitk::ScalarType QmitkMatchPointRegistrationVisualizer::GetSaveSpacing(mitk::ScalarType gridRes, + mitk::ScalarType spacing, unsigned int maxGridRes) const +{ + mitk::ScalarType newSpacing = spacing; + mitk::ScalarType scaling = gridRes / maxGridRes; + + if (scaling > 1.0) + { + newSpacing = spacing * scaling; + } + + return newSpacing; +} + +void QmitkMatchPointRegistrationVisualizer::OnUseFOVRefBtnPushed() +{ + if (this->m_spSelectedFOVRefNode.IsNotNull()) + { + assert(this->m_spSelectedFOVRefNode->GetData()); + assert(this->m_spSelectedFOVRefNode->GetData()->GetGeometry()); + + mitk::BaseGeometry* gridRef = this->m_spSelectedFOVRefNode->GetData()->GetGeometry(); + + mitk::Vector3D spacing = gridRef->GetSpacing(); + mitk::Point3D origin = gridRef->GetOrigin(); + mitk::Geometry3D::BoundsArrayType bounds = gridRef->GetBounds(); + mitk::AffineTransform3D::ConstPointer fovTransform = gridRef->GetIndexToWorldTransform(); + + + if (this->m_Controls->m_checkUseRefSize->isChecked()) + { + this->m_Controls->m_sbFOVSizeX->setValue((bounds[1] - bounds[0])*spacing[0]); + this->m_Controls->m_sbFOVSizeY->setValue((bounds[3] - bounds[2])*spacing[1]); + this->m_Controls->m_sbFOVSizeZ->setValue((bounds[5] - bounds[4])*spacing[2]); + } + + if (this->m_Controls->m_checkUseRefSpacing->isChecked()) + { + + this->m_Controls->m_sbGridSpX->setValue(GetSaveSpacing((bounds[1] - bounds[0]), spacing[0], 20)); + this->m_Controls->m_sbGridSpY->setValue(GetSaveSpacing((bounds[3] - bounds[2]), spacing[1], 20)); + this->m_Controls->m_sbGridSpZ->setValue(GetSaveSpacing((bounds[5] - bounds[4]), spacing[2], 20)); + + } + + if (this->m_Controls->m_checkUseRefOrigin->isChecked()) + { + this->m_Controls->m_sbFOVOriginX->setValue(origin[0]); + this->m_Controls->m_sbFOVOriginY->setValue(origin[1]); + this->m_Controls->m_sbFOVOriginZ->setValue(origin[2]); + } + + if (this->m_Controls->m_checkUseRefOrientation->isChecked()) + { + this->m_FOVRefOrientation = fovTransform->GetMatrix(); + this->UpdateOrientationMatrixWidget(); + } + + } +} + +void QmitkMatchPointRegistrationVisualizer::UpdateOrientationMatrixWidget() +{ + for (unsigned int r = 0; r < 3; ++r) + { + for (unsigned int c = 0; c < 3; ++c) + { + this->m_Controls->m_tableOrientation->item(r, + c)->setText(QString::number(this->m_FOVRefOrientation.GetVnlMatrix().get(r, c))); + } + } +} + +void QmitkMatchPointRegistrationVisualizer::InitRegNode() +{ + if (this->m_spSelectedRegNode.IsNotNull()) + { + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGrid, mitk::BoolProperty::New(true)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGlyph, mitk::BoolProperty::New(false)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisPoints, mitk::BoolProperty::New(false)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisDirection, + mitk::RegVisDirectionProperty::New()); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorStyle, + mitk::RegVisColorStyleProperty::New(1)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorUni, mitk::ColorProperty::New(0, + 0.5, 0)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridFrequence, + mitk::IntProperty::New(3)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridShowStart, + mitk::BoolProperty::New(false)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisGridStartColor, + mitk::ColorProperty::New(0.5, 0, 0)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVSize, + mitk::Vector3DProperty::New(mitk::Vector3D(100.0))); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVSpacing, + mitk::Vector3DProperty::New(mitk::Vector3D(5.0))); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor1Value, mitk::ColorProperty::New(0, + 0, 0.5)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Value, mitk::ColorProperty::New(0, + 0.7, 0)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor2Magnitude, + mitk::DoubleProperty::New(1)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Value, mitk::ColorProperty::New(1, + 1, 0)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor3Magnitude, + mitk::DoubleProperty::New(5)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Value, mitk::ColorProperty::New(1, + 0, 0)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColor4Magnitude, + mitk::DoubleProperty::New(15)); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisColorInterpolate, + mitk::BoolProperty::New(true)); + + mitk::Point3D origin; + origin.Fill(0.0); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrigin, + mitk::Point3dProperty::New(mitk::Point3D(origin))); + + mitk::Vector3D vec(0.0); + vec.SetElement(0, 1.0); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation1, + mitk::Vector3DProperty::New(vec)); + vec.Fill(0.0); + vec.SetElement(1, 1.0); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation2, + mitk::Vector3DProperty::New(vec)); + vec.Fill(0.0); + vec.SetElement(2, 1.0); + this->m_spSelectedRegNode->AddProperty(mitk::nodeProp_RegVisFOVOrientation3, + mitk::Vector3DProperty::New(vec)); + + } +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.h b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.h new file mode 100644 index 0000000000..e064d9bdd4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.h @@ -0,0 +1,162 @@ +/*=================================================================== + +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 __Q_MITK_MATCHPOINT_REGISTRATION_VISUALIZER_H +#define __Q_MITK_MATCHPOINT_REGISTRATION_VISUALIZER_H + +#include +#include + +#include + +#include + +#include + +#include "mitkMAPRegistrationWrapper.h" + +#include "ui_QmitkMatchPointRegistrationVisualizer.h" + + +/*! + \brief QmitkMatchPointRegistrationVisualizer + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkFunctionality + \ingroup ${plugin_target}_internal + */ +class QmitkMatchPointRegistrationVisualizer : public QmitkAbstractView +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + + static const std::string VIEW_ID; + + /** + * Creates smartpointer typedefs + */ + berryObjectMacro(QmitkMatchPointRegistrationVisualizer) + + QmitkMatchPointRegistrationVisualizer(); + + virtual void CreateQtPartControl(QWidget* parent); + + /** Returns the registration currently handled by the plugin. + * May return NULL, if no registration is selected/handled by + * the plugin*/ + mitk::MAPRegistrationWrapper* GetCurrentRegistration(); + + protected slots: + + /** + * @brief Connect all GUI elements to its corresponding slots + */ + virtual void CreateConnections(); + + void OnLockRegButtonPushed(); + void OnStyleButtonPushed(); + void OnDirectionChanged(int index); + + void OnUseFOVRefBtnPushed(); + void OnUpdateBtnPushed(); + + void OnColorInterpolationChecked(bool); + +protected: + virtual void SetFocus(); + + /// \brief called by QmitkFunctionality when DataManager's selection has changed + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList& nodes); + + void ActualizeRegInfo(mitk::MAPRegistrationWrapper* currentReg); + + Ui::MatchPointRegVisControls* m_Controls; + +private: + QWidget* m_Parent; + + void Error(QString msg); + + void CheckInputs(); + + /** Function returns the first data node containing a registration wrapper + * in the current selection of the data manager. If nothing is selected or + * no registration wrapper is selected it return NULL.*/ + mitk::DataNode::Pointer GetSelectedRegNode() const; + + /** If a registration node is set, this function determines the relevant referenced node. + * The reference node is the node of the target or moving data (depending on the selected directions) + * used to determine the* registration object. + * @return Pointer to the reference node (moving or target data of the registration algorithm run). + * Function may return NULL if the referenced node cannot be found or is not defined + * by the registration.*/ + mitk::DataNode::Pointer GetRefNodeOfReg(bool target) const; + + /** Methods returns the first node selected in the data manager that does + * NOT contain a registration wrapper and has a data pointer with a geometry. + * Returned pointer may be NULL if nothing is selected or no appropriate data + * node is selected.*/ + mitk::DataNode::Pointer GetSelectedDataNode(); + + /** Methods checks if the given gridRes is larger than maxGridRes and scales down the spacing if necessary. + * @param gridRes the resolution of the "grid". + * @param spacing the spacing that would be used on the grid. + * @param maxGridRes the maximum resolution of the "grid".*/ + mitk::ScalarType GetSaveSpacing(mitk::ScalarType gridRes, mitk::ScalarType spacing, + unsigned int maxGridRes) const; + + /** + * Checks for mandatory node properties and defines them with default values if they are missing.*/ + void InitRegNode(); + + /** + * Updates the gui controls regarding the current state of the instance.*/ + void ConfigureVisualizationControls(); + + /** + * Updates the properties of the selected node according to the states of the gui controls.*/ + void StoreStateInNode(); + + /** + * Updates the state of the gui controls according to the properties of the selected node.*/ + void LoadStateFromNode(); + + /** + * Checks accordung to the current direction if there is a default FOV ref and sets it, + * if the current FOV ref is not locked.*/ + void CheckAndSetDefaultFOVRef(); + + void UpdateOrientationMatrixWidget(); + + /**indicates if the gui updates is triggered internally or by user. Needed to + * avoid update loops by ConfigureVisualizationControlls();*/ + bool m_internalUpdateGuard; + + mitk::DataNode::Pointer m_spSelectedFOVRefNode; + mitk::DataNode::Pointer m_spSelectedRegNode; + + /**Used to store informations about the FOV reference orientation. Default is identity matrix.*/ + mitk::AffineTransform3D::MatrixType m_FOVRefOrientation; +}; + +#endif // MatchPoint_h + diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.ui b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.ui new file mode 100644 index 0000000000..283cae3c63 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/QmitkMatchPointRegistrationVisualizer.ui @@ -0,0 +1,1729 @@ + + + MatchPointRegVisControls + + + + 0 + 0 + 332 + 738 + + + + + 5 + + + 5 + + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 255 + 0 + 0 + + + + + + + + + 120 + 120 + 120 + + + + + + + + Warning: This plugin is in an experimental state! + + + + + + + Registration: + + + + + + + 3 + + + + + + 0 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Registration that should be used to map the moving image... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the selected registration for mapping + + + + + + + :/org.mitk.gui.qt.registration.visualizer/resources/icon_unlock.png + :/org.mitk.gui.qt.registration.visualizer/resources/icon_lock.png:/org.mitk.gui.qt.registration.visualizer/resources/icon_unlock.png + + + true + + + false + + + false + + + + + + + + + Info: + + + + + + + + 0 + 0 + + + + + 0 + 75 + + + + + 16777215 + 130 + + + + true + + + + + + + + 0 + 0 + + + + + + + false + + + + 5 + + + 5 + + + + + <html><head/><body><p>Updates the visualization with the current settings.</p></body></html> + + + Update visualization + + + false + + + + + + + Show mapping direction: + + + + + + + <html><head/><body><p>Select the direction/kernel of the registration you want to visualize:</p><p>- &quot;direct&quot;: select to show the direct mapping kernel (used for continuous spaced data like point sets).</p><p>- &quot;inverse&quot;: select to show the inverse mapping kernel (used for discrete spaced data like voxel images).</p><p><br/></p><p>If the selected registration does not support a direction, you cannot select it.</p></body></html> + + + + Direct + + + + + Inverse + + + + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + 5 + + + 0 + + + 5 + + + 0 + + + 5 + + + + + <html><head/><body><p>Select to vizualize registration via grid(s).</p></body></html> + + + Grid + + + true + + + true + + + true + + + + + + + true + + + Select to vizualize registration via glyphs. + + + Glyph + + + true + + + true + + + + + + + false + + + Select to vizualize registration via a pointset selected from the data manager... + + + Points + + + true + + + true + + + + + + + + + + 0 + + + + Visualization + + + + 5 + + + 5 + + + 5 + + + + + + + Color style: + + + + + + + + + uni color: + + + + + + + false + + + + 60 + 0 + + + + false + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + vector magnitude: + + + + + + + Color coding: + + + + + + 7 + + + 3 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + mm + + + + + + + small: + + + + + + + medium: + + + + + + + + 30 + 16777215 + + + + > + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 999.000000000000000 + + + 0.100000000000000 + + + + + + + 999.000000000000000 + + + + + + + large: + + + + + + + + 30 + 16777215 + + + + > + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + mm + + + + + + + 999.000000000000000 + + + + + + + mm + + + + + + + + 30 + 16777215 + + + + > + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + negligible: + + + + + + + + 50 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + 50 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + 50 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + 50 + 0 + + + + + 40 + 16777215 + + + + + + + + + + + + + interpolate colors + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + true + + + Grid + + + <html><head/><body><p>General grid visualization settings.</p></body></html> + + + + 5 + + + 5 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + 5 + + + 5 + + + + + Grid frequency: + + + + + + + <html><head/><body><p>Indicate the frequency of visible gridlines used for visualization.</p><p>e.g. 1: every line of the grid is visible; 2: only every second line is visible ...</p></body></html> + + + 200 + + + + + + + + + + 50 + false + + + + <html><head/><body><p>Allows that pixels may not be defined in the mapped image because they are outside of the field of view of the used input image.</p><p>The pixels will be marked with the given padding value.</p><p>If unchecked the mapping will be aborted in a case of undefined pixels.</p></body></html> + + + Show start grid + + + false + + + true + + + false + + + + 11 + + + 5 + + + 11 + + + 5 + + + + + Color + + + + + + + + 60 + 0 + + + + false + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 300 + + + + + + + + + FOV + + + <html><head/><body><p>Field of view settings (FOV) for vizualizing the grid correctly (its origin, size and orientation).</p></body></html> + + + + 5 + + + 5 + + + + + Size (in mm): + + + + + + + 0 + + + + + + 0 + 0 + + + + x: + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the size (in mm) of the grid in the x direction.</p></body></html> + + + 2 + + + 0.010000000000000 + + + 9999.000000000000000 + + + + + + + y: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the size (in mm) of the grid in the y direction.</p></body></html> + + + 2 + + + 0.010000000000000 + + + 9999.000000000000000 + + + + + + + z: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the size (in mm) of the grid in the z direction.</p></body></html> + + + 2 + + + 0.010000000000000 + + + 9999.000000000000000 + + + + + + + + + Origin (in mm): + + + + + + + 0 + + + + + + 0 + 0 + + + + x: + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the origin (in mm) of the grid in the x direction.</p></body></html> + + + -99999.000000000000000 + + + 99999.000000000000000 + + + + + + + y: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the origin (in mm) of the grid in the y direction.</p></body></html> + + + -99999.000000000000000 + + + 99999.000000000000000 + + + + + + + z: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the origin (in mm) of the grid in the z direction.</p></body></html> + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 0.000000000000000 + + + + + + + + + Spacing (in mm): + + + + + + + 0 + + + + + + 0 + 0 + + + + x: + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the spacing/resolution of the grid in the x direction.</p></body></html> + + + 0.010000000000000 + + + 9999.000000000000000 + + + 0.010000000000000 + + + + + + + y: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the spacing/resolution of the grid in the y direction.</p></body></html> + + + 0.010000000000000 + + + 9999.000000000000000 + + + 0.010000000000000 + + + + + + + z: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 10 + 0 + + + + + 50 + 16777215 + + + + <html><head/><body><p>Indicate the spacing/resolution of the grid in the z direction.</p></body></html> + + + 0.010000000000000 + + + 9999.000000000000000 + + + 0.010000000000000 + + + + + + + + + Orientation: + + + + + + + true + + + + 0 + 0 + + + + + 160 + 50 + + + + + 7 + + + + false + + + false + + + false + + + false + + + false + + + 50 + + + 20 + + + false + + + 15 + + + + R1 + + + + + R2 + + + + + R3 + + + + + C1 + + + + + C2 + + + + + C3 + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + 0 + + + ItemIsEnabled + + + + + + + + FOV Reverence: + + + + + + + 3 + + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 0 + 170 + 0 + + + + + + + + + 159 + 158 + 158 + + + + + + + + + 75 + true + + + + Registration that should be used to map the moving image... + + + QFrame::StyledPanel + + + 2 + + + 1 + + + + + + + + + + + 0 + 0 + + + + + 24 + 24 + + + + + 24 + 24 + + + + Lock the selected registration for mapping + + + + + + + :/org.mitk.gui.qt.registration.visualizer/resources/icon_unlock.png + :/org.mitk.gui.qt.registration.visualizer/resources/icon_lock.png:/org.mitk.gui.qt.registration.visualizer/resources/icon_unlock.png + + + true + + + false + + + false + + + + + + + + + + + size + + + true + + + + + + + origin + + + true + + + + + + + spacing + + + true + + + + + + + orientation + + + true + + + + + + + + + Use reference + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + ctkColorPickerButton + QPushButton +
ctkColorPickerButton.h
+
+
+ + + + + 5 + + + 5 + + + true + + + true + + + true + + +
diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.cpp new file mode 100644 index 0000000000..9cb784fc7f --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.cpp @@ -0,0 +1,43 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "org_mitk_gui_qt_matchpoint_visualizer_Activator.h" + +#include "QmitkMatchPointRegistrationVisualizer.h" + +ctkPluginContext* org_mitk_gui_qt_matchpoint_visualizer_Activator::m_Context = 0; + +void org_mitk_gui_qt_matchpoint_visualizer_Activator::start( + ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(QmitkMatchPointRegistrationVisualizer, context) + + m_Context = context; +} + +void org_mitk_gui_qt_matchpoint_visualizer_Activator::stop( + ctkPluginContext* context) +{ + Q_UNUSED(context) + + m_Context = 0; +} + +ctkPluginContext* org_mitk_gui_qt_matchpoint_visualizer_Activator::GetContext() +{ + return m_Context; +} diff --git a/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.h b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.h new file mode 100644 index 0000000000..5615a28bd4 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.matchpoint.visualizer/src/internal/org_mitk_gui_qt_matchpoint_visualizer_Activator.h @@ -0,0 +1,42 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef org_mitk_gui_qt_matchpoint_visualizer_Activator_h +#define org_mitk_gui_qt_matchpoint_visualizer_Activator_h + +#include + +class org_mitk_gui_qt_matchpoint_visualizer_Activator : + public QObject, public ctkPluginActivator +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_matchpoint_visualizer") + Q_INTERFACES(ctkPluginActivator) + +public: + + void start(ctkPluginContext* context); + void stop(ctkPluginContext* context); + + static ctkPluginContext* GetContext(); + +private: + + static ctkPluginContext* m_Context; + +}; // org_mitk_gui_qt_matchpoint_visualizer_Activator + +#endif // org_mitk_gui_qt_matchpoint_visualizer_Activator_h diff --git a/Plugins/org.mitk.matchpoint.core.helper/CMakeLists.txt b/Plugins/org.mitk.matchpoint.core.helper/CMakeLists.txt new file mode 100644 index 0000000000..112a65a0f1 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/CMakeLists.txt @@ -0,0 +1,8 @@ +project(org_mitk_matchpoint_core_helper) + +mitk_create_plugin( + EXPORT_DIRECTIVE MITK_MATCHPOINT_CORE_HELPER_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgets MitkQtWidgetsExt MitkMatchPointRegistration + PACKAGE_DEPENDS Qt5|UiTools +) diff --git a/Plugins/org.mitk.matchpoint.core.helper/files.cmake b/Plugins/org.mitk.matchpoint.core.helper/files.cmake new file mode 100644 index 0000000000..4fca84b3fa --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/files.cmake @@ -0,0 +1,56 @@ +set(SRC_CPP_FILES + mitkMAPAlgorithmInfoSelection.cpp + mitkMAPAlgorithmInfoObject.cpp +) + +set(INTERNAL_CPP_FILES + org_mitk_matchpoint_core_helper_Activator.cpp + MatchPointBrowserPreferencesPage.cpp + MatchPointBrowserConstants.cpp + QmitkDirectoryListWidget.cpp + QmitkFileListWidget.cpp +) + +set(UI_FILES + src/internal/QmitkPathListWidget.ui +) + +set(H_FILES + src/MatchPointBrowserConstants.h + src/mitkMAPAlgorithmInfoSelection.h + src/mitkMAPAlgorithmInfoObject.h +) + +set(MOC_H_FILES + src/internal/org_mitk_matchpoint_core_helper_Activator.h + src/internal/MatchPointBrowserPreferencesPage.h + src/internal/QmitkDirectoryListWidget.h + src/internal/QmitkFileListWidget.h +) + +# list of resource files which can be used by the plug-in +# system without loading the plug-ins shared library, +# for example the icon used in the menu and tabs for the +# plug-in views in the workbench +set(CACHED_RESOURCE_FILES + plugin.xml + + resources/MAPRegData.png +) + +# list of Qt .qrc files which contain additional resources +# specific to this plugin +set(QRC_FILES + resources/QmitkMatchPointCore.qrc +) + +set(CPP_FILES ) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +foreach(file ${INTERNAL_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/internal/${file}) +endforeach(file ${INTERNAL_CPP_FILES}) + diff --git a/Plugins/org.mitk.matchpoint.core.helper/manifest_headers.cmake b/Plugins/org.mitk.matchpoint.core.helper/manifest_headers.cmake new file mode 100644 index 0000000000..fda5847d5e --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/manifest_headers.cmake @@ -0,0 +1,5 @@ +SET(Plugin-Name "MAP MITK Core Helper") +SET(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "http://www.mitk.org") +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager) diff --git a/Plugins/org.mitk.matchpoint.core.helper/plugin.xml b/Plugins/org.mitk.matchpoint.core.helper/plugin.xml new file mode 100644 index 0000000000..3b7a590e52 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/plugin.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Plugins/org.mitk.matchpoint.core.helper/resources/MAPRegData.png b/Plugins/org.mitk.matchpoint.core.helper/resources/MAPRegData.png new file mode 100644 index 0000000000..64eb6fba62 Binary files /dev/null and b/Plugins/org.mitk.matchpoint.core.helper/resources/MAPRegData.png differ diff --git a/Plugins/org.mitk.matchpoint.core.helper/resources/QmitkMatchPointCore.qrc b/Plugins/org.mitk.matchpoint.core.helper/resources/QmitkMatchPointCore.qrc new file mode 100644 index 0000000000..9674bf8181 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/resources/QmitkMatchPointCore.qrc @@ -0,0 +1,5 @@ + + + MAPRegData.png + + diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/MatchPointBrowserConstants.h b/Plugins/org.mitk.matchpoint.core.helper/src/MatchPointBrowserConstants.h new file mode 100644 index 0000000000..c9ac4d6f80 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/MatchPointBrowserConstants.h @@ -0,0 +1,79 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MatchPointBrowserConstants_h +#define MatchPointBrowserConstants_h + +#include +#include + +#include "org_mitk_matchpoint_core_helper_Export.h" + +/** + * \class MatchPointBrowserConstants + * \brief Structure to define a namespace for constants used privately within this view. + */ +struct MITK_MATCHPOINT_CORE_HELPER_EXPORT MatchPointBrowserConstants +{ + /** + * \brief The name of the preferences node containing the list of directories to scan for + * MatchPoint Deployed Registration Algorithms (MDRA). + */ + static const std::string MDAR_DIRECTORIES_NODE_NAME; + + /** + * \brief The name of the preferences node containing the additional MatchPoint Deployed Registration Algorithms (MDRA) + * that should be explicitly checked/loaded. + */ + static const std::string MDAR_FILES_NODE_NAME; + + /** + * \brief The name of the preferences node containing whether we are producing debug output. + */ + static const std::string DEBUG_OUTPUT_NODE_NAME; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading MDRAs from the application directory. + */ + static const std::string LOAD_FROM_APPLICATION_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading MDRAs from the users home directory. + */ + static const std::string LOAD_FROM_HOME_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading MDRAs from the applications current working directory. + */ + static const std::string LOAD_FROM_CURRENT_DIR; + + /** + * \brief The name of the preferences node containing a boolean describing whether + * we are loading MDRAs from the directory specified in MDRA_MODULE_LOAD_PATH. + */ + static const std::string LOAD_FROM_AUTO_LOAD_DIR; + + /** + * \brief The View ID = org.mitk.gui.qt.algorithm.browser, and should match that in plugin.xml. + */ + static const std::string VIEW_ID; + +}; + +#endif // MatchPointBrowserConstants_h diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmProfileViewer.h b/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmProfileViewer.h new file mode 100644 index 0000000000..838c9cb6ea --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmProfileViewer.h @@ -0,0 +1,54 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef QMITK_ALGORITHM_PROFILE_VIEWER_H +#define QMITK_ALGORITHM_PROFILE_VIEWER_H + +#include + +#include "org_mitk_matchpoint_core_helper_Export.h" + +#include "ui_QmitkAlgorithmProfileViewer.h" +#include + +/** + * \class QmitkAlgorithmProfileViewer + * \brief Widget that views the information and profile of an algorithm stored in an DLLInfo object. + */ +class MITK_MATCHPOINT_CORE_HELPER_EXPORT QmitkAlgorithmProfileViewer : public QWidget, private Ui::QmitkAlgorithmProfileViewer +{ + Q_OBJECT + +public: + QmitkAlgorithmProfileViewer(QWidget* parent=0); + + /** + * \brief Updates the widget according to the new info. + * \param pointer to the info instance. + * \remark The DLLInfo is not stored internally or as reference + * to update the widget you must use the updateInfo() method. + */ + void updateInfo(const map::deployment::DLLInfo* newInfo); + +public Q_SLOTS: + /** + * \brief Slot that can be used to trigger updateInfo(); + */ + void OnInfoChanged(const map::deployment::DLLInfo* newInfo); +}; + +#endif // QmitkAlgorithmProfileViewer_H diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmSettingsConfig.h b/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmSettingsConfig.h new file mode 100644 index 0000000000..f9b684c6d8 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/QmitkAlgorithmSettingsConfig.h @@ -0,0 +1,60 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#ifndef QMITK_ALGORITHM_SETTINGS_CONFIG_H +#define QMITK_ALGORITHM_SETTINGS_CONFIG_H + +#include +#include + +#include + +#include "mitkQMAPAlgorithmModel.h" + +#include "org_mitk_matchpoint_core_helper_Export.h" + +#include "ui_QmitkAlgorithmSettingsConfig.h" + +/** + * \class QmitkAlgorithmSettingsConfig + * \brief Widget that views the information and profile of an algorithm stored in an DLLInfo object. + */ +class MITK_MATCHPOINT_CORE_HELPER_EXPORT QmitkAlgorithmSettingsConfig : public QWidget, private Ui::QmitkAlgorithmSettingsConfig +{ + Q_OBJECT + +public: + QmitkAlgorithmSettingsConfig(QWidget* parent=0); + + /** + * \brief Changes the current algorithm and updates widget accordingly. + * \param pointer to the algorithm instance. + */ + void setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg); + + map::algorithm::RegistrationAlgorithmBase* getAlgorithm(); + +protected: + /** Pointer to the algorithm that should be configured */ + map::algorithm::RegistrationAlgorithmBase::Pointer m_currentAlg; + + // control the properties of the selected algorithm + mitk::QMAPAlgorithmModel* m_AlgorithmModel; + QSortFilterProxyModel* m_ProxyModel; +}; + +#endif // QmitkAlgorithmSettingsConfig_H diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserConstants.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserConstants.cpp new file mode 100644 index 0000000000..041b295086 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserConstants.cpp @@ -0,0 +1,26 @@ +/*=================================================================== + +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 "MatchPointBrowserConstants.h" + +const std::string MatchPointBrowserConstants::VIEW_ID = "org.mitk.gui.qt.algorithm.browser"; +const std::string MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME = "Deployed algorithm directories"; +const std::string MatchPointBrowserConstants::MDAR_FILES_NODE_NAME = "Deployed algorithms"; +const std::string MatchPointBrowserConstants::DEBUG_OUTPUT_NODE_NAME = "debug output"; +const std::string MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR = "load from application dir"; +const std::string MatchPointBrowserConstants::LOAD_FROM_HOME_DIR = "load from home dir"; +const std::string MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR = "load from current dir"; +const std::string MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR = "load from auto-load dir"; \ No newline at end of file diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp new file mode 100644 index 0000000000..56254f8163 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.cpp @@ -0,0 +1,160 @@ +/*=================================================================== + +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 "MatchPointBrowserPreferencesPage.h" +#include "MatchPointBrowserConstants.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "QmitkDirectoryListWidget.h" +#include "QmitkFileListWidget.h" + +//----------------------------------------------------------------------------- +MatchPointBrowserPreferencesPage::MatchPointBrowserPreferencesPage() +: m_MainControl(0) +, m_AlgDirectories(0) +, m_AlgFiles(0) +, m_LoadFromHomeDir(0) +, m_LoadFromCurrentDir(0) +, m_LoadFromApplicationDir(0) +, m_LoadFromAutoLoadPathDir(0) +, m_BrowserPreferencesNode(0) +{ + +} + + +//----------------------------------------------------------------------------- +MatchPointBrowserPreferencesPage::~MatchPointBrowserPreferencesPage() +{ + +} + + +//----------------------------------------------------------------------------- +void MatchPointBrowserPreferencesPage::Init(berry::IWorkbench::Pointer ) +{ + +} + + +//----------------------------------------------------------------------------- +void MatchPointBrowserPreferencesPage::CreateQtControl(QWidget* parent) +{ + berry::IPreferencesService* prefService + = berry::Platform::GetPreferencesService(); + + QString id = tr("/") + tr(MatchPointBrowserConstants::VIEW_ID.c_str()); + m_BrowserPreferencesNode = prefService->GetSystemPreferences()->Node(id); + + m_MainControl = new QWidget(parent); + + m_AlgDirectories = new QmitkDirectoryListWidget(m_MainControl); + m_AlgDirectories->m_Label->setText("Select directories to scan:"); + m_AlgFiles = new QmitkFileListWidget(m_MainControl); + m_AlgFiles->m_Label->setText("Select additional executables:"); + m_DebugOutput = new QCheckBox(m_MainControl); + + m_LoadFromAutoLoadPathDir = new QCheckBox(m_MainControl); + m_LoadFromApplicationDir = new QCheckBox(m_MainControl); + m_LoadFromHomeDir = new QCheckBox(m_MainControl); + m_LoadFromCurrentDir = new QCheckBox(m_MainControl); + + QFormLayout *formLayout = new QFormLayout; + formLayout->addRow("show debug output:", m_DebugOutput); + formLayout->addRow("scan home directory:", m_LoadFromHomeDir); + formLayout->addRow("scan current directory:", m_LoadFromCurrentDir); + formLayout->addRow("scan installation directory:", m_LoadFromApplicationDir); + formLayout->addRow("scan MAP_MDRA_LOAD_PATH:", m_LoadFromAutoLoadPathDir); + formLayout->addRow("additional algorithm directories:", m_AlgDirectories); + formLayout->addRow("additional algorithms:", m_AlgFiles); + + m_MainControl->setLayout(formLayout); + + this->Update(); +} + + +//----------------------------------------------------------------------------- +QWidget* MatchPointBrowserPreferencesPage::GetQtControl() const +{ + return m_MainControl; +} + + +//----------------------------------------------------------------------------- +QString MatchPointBrowserPreferencesPage::ConvertToString( const QStringList& list ) +{ + QString output; + for (int i = 0; i < list.count(); i++) + { + QString path = list[i] + ";"; + output = output + path; + } + return output; +} + +//----------------------------------------------------------------------------- +bool MatchPointBrowserPreferencesPage::PerformOk() +{ + m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::DEBUG_OUTPUT_NODE_NAME.c_str(), m_DebugOutput->isChecked()); + m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), m_LoadFromApplicationDir->isChecked()); + m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), m_LoadFromHomeDir->isChecked()); + m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), m_LoadFromCurrentDir->isChecked()); + m_BrowserPreferencesNode->PutBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), m_LoadFromAutoLoadPathDir->isChecked()); + + QString paths = this->ConvertToString(m_AlgDirectories->directories()); + m_BrowserPreferencesNode->Put(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), paths); + + QString modules = this->ConvertToString(m_AlgFiles->files()); + m_BrowserPreferencesNode->Put(MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), modules); + + return true; +} + + +//----------------------------------------------------------------------------- +void MatchPointBrowserPreferencesPage::PerformCancel() +{ +} + + +//----------------------------------------------------------------------------- +void MatchPointBrowserPreferencesPage::Update() +{ + m_DebugOutput->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::DEBUG_OUTPUT_NODE_NAME.c_str(), false)); + m_LoadFromApplicationDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_APPLICATION_DIR.c_str(), true)); + m_LoadFromHomeDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_HOME_DIR.c_str(), false)); + m_LoadFromCurrentDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_CURRENT_DIR.c_str(), false)); + m_LoadFromAutoLoadPathDir->setChecked(m_BrowserPreferencesNode->GetBool(MatchPointBrowserConstants::LOAD_FROM_AUTO_LOAD_DIR.c_str(), false)); + + QString paths = m_BrowserPreferencesNode->Get(MatchPointBrowserConstants::MDAR_DIRECTORIES_NODE_NAME.c_str(), tr("")); + QStringList directoryList = paths.split(";", QString::SkipEmptyParts); + m_AlgDirectories->setDirectories(directoryList); + + QString files = m_BrowserPreferencesNode->Get(MatchPointBrowserConstants::MDAR_FILES_NODE_NAME.c_str(), tr("")); + QStringList fileList = files.split(";", QString::SkipEmptyParts); + m_AlgFiles->setFiles(fileList); +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.h b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.h new file mode 100644 index 0000000000..56028f3ec3 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/MatchPointBrowserPreferencesPage.h @@ -0,0 +1,98 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef __MATCHPOINT_BROWSER_PREFERENCE_PAGE_H +#define __MATCHPOINT_BROWSER_PREFERENCE_PAGE_H + +#include "berryIQtPreferencePage.h" + +class QWidget; +class QCheckBox; +class QComboBox; +class QSpinBox; +class QmitkDirectoryListWidget; +class QmitkFileListWidget; +class ctkDirectoryButton; + +class berryIPreferences; + +/** + * \class MatchPointBrowserPreferencesPage + * \brief Preference page for the MatchPoint Browser plugin + */ +class MatchPointBrowserPreferencesPage : public QObject, public berry::IQtPreferencePage +{ + Q_OBJECT + Q_INTERFACES(berry::IPreferencePage) + +public: + MatchPointBrowserPreferencesPage(); + ~MatchPointBrowserPreferencesPage(); + + /** + * \brief Called by framework to initialise this preference page, but currently does nothing. + * \param workbench The workbench. + */ + void Init(berry::IWorkbench::Pointer workbench); + + /** + * \brief Called by framework to create the GUI, and connect signals and slots. + * \param widget The Qt widget that acts as parent to all GUI components, as this class itself is not derived from QWidget. + */ + void CreateQtControl(QWidget* widget); + + /** + * \brief Required by framework to get hold of the GUI. + * \return QWidget* the top most QWidget for the GUI. + */ + QWidget* GetQtControl() const; + + /** + * \see IPreferencePage::PerformOk + */ + virtual bool PerformOk(); + + /** + * \see IPreferencePage::PerformCancel + */ + virtual void PerformCancel(); + + /** + * \see IPreferencePage::Update + */ + virtual void Update(); + + public slots: + +protected: + + QWidget* m_MainControl; + QCheckBox* m_DebugOutput; + QmitkDirectoryListWidget* m_AlgDirectories; + QmitkFileListWidget* m_AlgFiles; + QCheckBox* m_LoadFromHomeDir; + QCheckBox* m_LoadFromCurrentDir; + QCheckBox* m_LoadFromApplicationDir; + QCheckBox* m_LoadFromAutoLoadPathDir; + + berry::IPreferences::Pointer m_BrowserPreferencesNode; + +private: + + QString ConvertToString(const QStringList& list); +}; + +#endif // COMMANDLINEMODULESPREFERENCESPAGE_H diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.cpp new file mode 100644 index 0000000000..1197f9f216 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.cpp @@ -0,0 +1,167 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + + +#include "QmitkAlgorithmProfileViewer.h" + +#include +#include + +QmitkAlgorithmProfileViewer::QmitkAlgorithmProfileViewer(QWidget*) +{ + this->setupUi(this); +} + +void QmitkAlgorithmProfileViewer::OnInfoChanged(const map::deployment::DLLInfo* newInfo) +{ + updateInfo(newInfo); +} + +std::string AddInfoTableRow(const std::string& name, + const ::map::algorithm::profile::ValueListType& values, + const std::string& defaultStr ="") +{ + std::stringstream descriptionString; + descriptionString << ""<"; + + if (!values.empty()) + { + for (::map::algorithm::profile::ValueListType::const_iterator pos = values.begin(); pos!=values.end();++pos) + { + if (pos != values.begin()) + { + descriptionString << "
"; + } + descriptionString << *pos; + } + } + else + { + if (defaultStr.empty()) + { + descriptionString << "unknown / not defined"; + } + else + { + descriptionString << defaultStr; + } + } + + descriptionString << ""; + + return descriptionString.str(); +} + +void QmitkAlgorithmProfileViewer::updateInfo(const map::deployment::DLLInfo* newInfo) +{ + if( !newInfo ) + { + this->m_teAlgorithmDetails->clear(); + } + else + { + std::stringstream descriptionString; + + ::map::structuredData::Element::Pointer algProfile = ::map::algorithm::profile::parseProfileString(newInfo->getAlgorithmProfileStr()); + // create description string + descriptionString << "

Identification

Namespace: "<< newInfo->getAlgorithmUID().getNamespace() << "
" + << "Name: "<< newInfo->getAlgorithmUID().getName() << "
" + << "Version: "<< newInfo->getAlgorithmUID().getVersion() << "
" + << "BuildTag: "<< newInfo->getAlgorithmUID().getBuildTag() << "
" + << "Location: "<< newInfo->getLibraryFilePath() << "

"; + + descriptionString << "

Description

"<< ::map::algorithm::profile::getDescription(algProfile)<< "

"; + descriptionString << "

Keywords

"; + ::map::algorithm::profile::ValueListType keys = ::map::algorithm::profile::getKeywords(algProfile); + for (::map::algorithm::profile::ValueListType::const_iterator keyPos = keys.begin(); keyPos!=keys.end();++keyPos) + { + if (keyPos != keys.begin()) + { + descriptionString << "; "; + } + descriptionString << *keyPos; + } + descriptionString << "

"; + + descriptionString << "

Characteristics

"; + descriptionString << AddInfoTableRow("data type(s)", ::map::algorithm::profile::getDataType(algProfile)); + descriptionString << AddInfoTableRow("computation style", ::map::algorithm::profile::getComputationStyle(algProfile)); + if (::map::algorithm::profile::isDeterministic(algProfile)) + { + descriptionString << ""; + } + else + { + descriptionString << ""; + } + descriptionString << AddInfoTableRow("resolution style", ::map::algorithm::profile::getResolutionStyle(algProfile)); + + unsigned int dimension; + + descriptionString << ""; + descriptionString << AddInfoTableRow("moving modality", ::map::algorithm::profile::getMovingModality(algProfile)); + + descriptionString << ""; + descriptionString << AddInfoTableRow("target modality", ::map::algorithm::profile::getTargetModality(algProfile)); + + descriptionString << AddInfoTableRow("subject", ::map::algorithm::profile::getSubject(algProfile)); + descriptionString << AddInfoTableRow("object", ::map::algorithm::profile::getObject(algProfile)); + descriptionString << AddInfoTableRow("transform model", ::map::algorithm::profile::getTransformModel(algProfile)); + descriptionString << AddInfoTableRow("transform domain", ::map::algorithm::profile::getTransformDomain(algProfile)); + descriptionString << AddInfoTableRow("metric", ::map::algorithm::profile::getMetric(algProfile)); + descriptionString << AddInfoTableRow("optimization", ::map::algorithm::profile::getOptimization(algProfile)); + descriptionString << AddInfoTableRow("interaction", ::map::algorithm::profile::getInteraction(algProfile)); + descriptionString << "
deterministic:yes
deterministic:no
moving dim:"; + if (::map::algorithm::profile::getMovingDimensions(algProfile,dimension)) + { + descriptionString << map::core::convert::toStr(dimension)<<"D"; + } + else + { + descriptionString << "unknown / not defined"; + } + descriptionString<<"
target dim:"; + if (::map::algorithm::profile::getTargetDimensions(algProfile,dimension)) + { + descriptionString << map::core::convert::toStr(dimension)<<"D"; + } + else + { + descriptionString << "unknown / not defined"; + } + descriptionString<<"
"; + + descriptionString << "

Contact & Usage

"; + descriptionString << AddInfoTableRow("contact", ::map::algorithm::profile::getContact(algProfile)); + std::string terms; + descriptionString << ""; + descriptionString << AddInfoTableRow("citation", ::map::algorithm::profile::getCitation(algProfile)); + descriptionString <<"
terms:"; + if (::map::algorithm::profile::getTerms(algProfile,terms)) + { + descriptionString<unknown / not defined"; + } + descriptionString <<"
"; + + // update the info label + this->m_teAlgorithmDetails->clear(); + this->m_teAlgorithmDetails->insertHtml( QString::fromStdString( descriptionString.str() ) ); + } +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.ui b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.ui new file mode 100644 index 0000000000..57e9321dc9 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmProfileViewer.ui @@ -0,0 +1,61 @@ + + + QmitkAlgorithmProfileViewer + + + + 0 + 0 + 554 + 898 + + + + Form + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QFrame::StyledPanel + + + false + + + QTextEdit::WidgetWidth + + + 0 + + + true + + + Qt::NoTextInteraction + + + + + + + + diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.cpp new file mode 100644 index 0000000000..b762e3ed98 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.cpp @@ -0,0 +1,60 @@ +/*=================================================================== + +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 "QmitkAlgorithmSettingsConfig.h" + +#include +#include + +QmitkAlgorithmSettingsConfig::QmitkAlgorithmSettingsConfig(QWidget*) +{ + this->setupUi(this); + + m_AlgorithmModel = new mitk::QMAPAlgorithmModel(this); + m_ProxyModel = new QSortFilterProxyModel(this); + + // configure property model/view/widget + m_ProxyModel->setSourceModel(m_AlgorithmModel); + m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_ProxyModel->setDynamicSortFilter(true); + + this->m_AlgoPropertiesView->setModel(m_ProxyModel); + this->m_AlgoPropertiesView->setSortingEnabled(true); + this->m_AlgoPropertiesView->setAlternatingRowColors(true); + this->m_AlgoPropertiesView->setSelectionMode(QAbstractItemView::SingleSelection); + this->m_AlgoPropertiesView->setSelectionBehavior(QAbstractItemView::SelectItems); +} + +void setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg); + +map::algorithm::RegistrationAlgorithmBase* getAlgorithm(); + +void QmitkAlgorithmSettingsConfig::setAlgorithm(map::algorithm::RegistrationAlgorithmBase* alg) +{ + if (alg != this->m_currentAlg) + { + this->m_currentAlg = alg; + this->m_AlgorithmModel->SetAlgorithm(this->m_currentAlg); + + this->m_AlgoPropertiesView->setWindowModified(true); + this->m_AlgoPropertiesView->update(); + } +} + +map::algorithm::RegistrationAlgorithmBase* QmitkAlgorithmSettingsConfig::getAlgorithm() +{ + return this->m_currentAlg; +} \ No newline at end of file diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.ui b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.ui new file mode 100644 index 0000000000..ffc420825d --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkAlgorithmSettingsConfig.ui @@ -0,0 +1,80 @@ + + + QmitkAlgorithmSettingsConfig + + + + 0 + 0 + 271 + 534 + + + + Form + + + + 0 + + + 0 + + + + + 0 + + + + Properties + + + + 0 + + + + + + 0 + 0 + + + + + 250 + 0 + + + + true + + + true + + + true + + + + + + + + false + + + Configuration of the multi resolution scheme of an algorithm. + + + Multi resolution + + + + + + + + + diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.cpp new file mode 100644 index 0000000000..a275a4108c --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.cpp @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +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 "QmitkDirectoryListWidget.h" + +#include +#include + +//----------------------------------------------------------------------------- +QmitkDirectoryListWidget::QmitkDirectoryListWidget(QWidget*) +{ + this->setupUi(this); + this->m_PathListWidget->setMode(ctkPathListWidget::DirectoriesOnly); + this->m_PathListWidget->setDirectoryOptions(ctkPathListWidget::Exists | ctkPathListWidget::Readable | ctkPathListWidget::Executable); + this->m_PathListButtonsWidget->init(this->m_PathListWidget); + this->m_PathListButtonsWidget->setOrientation(Qt::Vertical); + connect(this->m_PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), this, SLOT(OnPathsChanged(QStringList, QStringList))); +} + + +//----------------------------------------------------------------------------- +void QmitkDirectoryListWidget::OnPathsChanged(const QStringList& before, const QStringList& after) +{ + emit pathsChanged(before, after); +} + + +//----------------------------------------------------------------------------- +QStringList QmitkDirectoryListWidget::directories(bool absolutePath) const +{ + return this->m_PathListWidget->directories(absolutePath); +} + + +//----------------------------------------------------------------------------- +void QmitkDirectoryListWidget::setDirectories(const QStringList& paths) +{ + this->m_PathListWidget->setPaths(paths); +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.h b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.h new file mode 100644 index 0000000000..4abeacba46 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkDirectoryListWidget.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +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 QMITKDIRECTORYLISTWIDGET_H +#define QMITKDIRECTORYLISTWIDGET_H + +#include "ui_QmitkPathListWidget.h" +#include + +/** + * \class QmitkDirectoryListWidget + * \brief Widget to contain a ctkPathListWidget and a ctkPathListButtonsWidget + * and provide simple directory access for readable, executable directories. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cmdlinemodules_internal + */ +class QmitkDirectoryListWidget : public QWidget, public Ui::QmitkPathListWidget +{ + Q_OBJECT + +public: + QmitkDirectoryListWidget(QWidget* parent=0); + + /** + * \brief Get all directory entries. + * \param absolutePath If true, resolve all entries to absolute paths. + * \return A list of all directory entries. + */ + QStringList directories(bool absolutePath = false) const; + + /** + * \brief Sets the list of directory entries. + * \param paths The new path list. + */ + void setDirectories(const QStringList& paths); + +Q_SIGNALS: + + void pathsChanged(const QStringList&, const QStringList&); + +private Q_SLOTS: + + void OnPathsChanged(const QStringList&, const QStringList&); +}; + +#endif // QMITKDIRECTORYLISTWIDGET_H diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.cpp new file mode 100644 index 0000000000..a1bf1bdec2 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.cpp @@ -0,0 +1,51 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +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 "QmitkFileListWidget.h" + +#include +#include + +//----------------------------------------------------------------------------- +QmitkFileListWidget::QmitkFileListWidget(QWidget*) +{ + this->setupUi(this); + this->m_PathListWidget->setMode(ctkPathListWidget::FilesOnly); + this->m_PathListWidget->setFileOptions(ctkPathListWidget::Exists | ctkPathListWidget::Readable | ctkPathListWidget::Executable); + this->m_PathListButtonsWidget->init(this->m_PathListWidget); + this->m_PathListButtonsWidget->setOrientation(Qt::Vertical); + connect(this->m_PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), this, SLOT(OnPathsChanged(QStringList, QStringList))); +} + + +//----------------------------------------------------------------------------- +void QmitkFileListWidget::OnPathsChanged(const QStringList& before, const QStringList& after) +{ + emit pathsChanged(before, after); +} + + +//----------------------------------------------------------------------------- +QStringList QmitkFileListWidget::files(bool absolutePath) const +{ + return this->m_PathListWidget->files(absolutePath); +} + + +//----------------------------------------------------------------------------- +void QmitkFileListWidget::setFiles(const QStringList& paths) +{ + this->m_PathListWidget->setPaths(paths); +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.h b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.h new file mode 100644 index 0000000000..7339cb8a95 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkFileListWidget.h @@ -0,0 +1,58 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) University College London (UCL). +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 QMITKFILELISTWIDGET_H +#define QMITKFILELISTWIDGET_H + +#include "ui_QmitkPathListWidget.h" +#include + +/** + * \class QmitkFileListWidget + * \brief Widget to contain a ctkPathListWidget and a ctkPathListButtonsWidget + * and provide simple file access for readable, executable files. + * \author Matt Clarkson (m.clarkson@ucl.ac.uk) + * \ingroup org_mitk_gui_qt_cmdlinemodules_internal + */ +class QmitkFileListWidget : public QWidget, public Ui::QmitkPathListWidget +{ + Q_OBJECT + +public: + QmitkFileListWidget(QWidget* parent=0); + + /** + * \brief Get all file entries. + * \param absolutePath If true, resolve all entries to absolute paths. + * \return A list of all file entries. + */ + QStringList files(bool absolutePath = false) const; + + /** + * \brief Sets the list of file entries. + * \param paths The new path list. + */ + void setFiles(const QStringList& paths); + +Q_SIGNALS: + + void pathsChanged(const QStringList&, const QStringList&); + +private Q_SLOTS: + + void OnPathsChanged(const QStringList&, const QStringList&); +}; + +#endif // QMITKDIRECTORYLISTWIDGET_H diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkPathListWidget.ui b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkPathListWidget.ui new file mode 100644 index 0000000000..1c21a8441d --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/QmitkPathListWidget.ui @@ -0,0 +1,74 @@ + + + QmitkPathListWidget + + + + 0 + 0 + 449 + 312 + + + + Form + + + + + + Enter Label Text + + + true + + + + + + + Qt::ElideMiddle + + + + + + + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + ctkPathListButtonsWidget + QWidget +
ctkPathListButtonsWidget.h
+
+ + ctkPathListWidget + QListView +
ctkPathListWidget.h
+
+
+ + +
diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.cpp new file mode 100644 index 0000000000..d00f67b8fe --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.cpp @@ -0,0 +1,69 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_matchpoint_core_helper_Activator.h" + +#include "MatchPointBrowserPreferencesPage.h" + +#include "QmitkNodeDescriptorManager.h" +#include "mitkNodePredicateDataType.h" + + +ctkPluginContext* org_mitk_matchpoint_core_helper_Activator::m_Context = nullptr; +org_mitk_matchpoint_core_helper_Activator* +org_mitk_matchpoint_core_helper_Activator::m_Instance = nullptr; + +org_mitk_matchpoint_core_helper_Activator::org_mitk_matchpoint_core_helper_Activator() +{ + m_Instance = this; +} + +org_mitk_matchpoint_core_helper_Activator::~org_mitk_matchpoint_core_helper_Activator() +{ + m_Instance = nullptr; +} + +void org_mitk_matchpoint_core_helper_Activator::start(ctkPluginContext* context) +{ + BERRY_REGISTER_EXTENSION_CLASS(MatchPointBrowserPreferencesPage, context) + + this->m_Context = context; + + QmitkNodeDescriptorManager* manager = QmitkNodeDescriptorManager::GetInstance(); + + mitk::NodePredicateDataType::Pointer isMITKRegistrationWrapper = + mitk::NodePredicateDataType::New("MAPRegistrationWrapper"); + manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("MAPRegistrationWrapper"), + QString(":/QmitkMatchPointCore/MAPRegData.png"), isMITKRegistrationWrapper, manager)); +} + +void org_mitk_matchpoint_core_helper_Activator::stop(ctkPluginContext* context) +{ + Q_UNUSED(context) + + this->m_Context = NULL; +} + +ctkPluginContext* org_mitk_matchpoint_core_helper_Activator::getContext() +{ + return m_Context; +} + +org_mitk_matchpoint_core_helper_Activator* +org_mitk_matchpoint_core_helper_Activator::getDefault() +{ + return m_Instance; +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.h b/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.h new file mode 100644 index 0000000000..9a7de83b5f --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/internal/org_mitk_matchpoint_core_helper_Activator.h @@ -0,0 +1,48 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef org_mitk_matchpoint_core_helper_Activator_h +#define org_mitk_matchpoint_core_helper_Activator_h + +#include + +class org_mitk_matchpoint_core_helper_Activator : + public berry::AbstractUICTKPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_matchpoint_core_helper") + Q_INTERFACES(ctkPluginActivator) + +public: + + org_mitk_matchpoint_core_helper_Activator(); + ~org_mitk_matchpoint_core_helper_Activator(); + + void start(ctkPluginContext* context) override; + void stop(ctkPluginContext* context) override; + + static org_mitk_matchpoint_core_helper_Activator* getDefault(); + + static ctkPluginContext* getContext(); + +private: + + static ctkPluginContext* m_Context; + static org_mitk_matchpoint_core_helper_Activator* m_Instance; + +}; // org_mitk_gui_qt_algorithmcontrol_Activator + +#endif // org_mitk_gui_qt_algorithmcontrol_Activator_h diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.cpp new file mode 100644 index 0000000000..b8ad7dd3a4 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.cpp @@ -0,0 +1,49 @@ +/*=================================================================== + +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 "mitkMAPAlgorithmInfoObject.h" + +namespace mitk +{ + +MAPAlgorithmInfoObject::MAPAlgorithmInfoObject() : + m_Info(NULL) +{ + +} + +MAPAlgorithmInfoObject::MAPAlgorithmInfoObject(::map::deployment::DLLInfo::ConstPointer info) : + m_Info(info) +{ + +} + +const ::map::deployment::DLLInfo* MAPAlgorithmInfoObject::GetInfo() const +{ + return m_Info; +} + +bool MAPAlgorithmInfoObject::operator==(const berry::Object* obj) const +{ + if (const MAPAlgorithmInfoObject* other = dynamic_cast(obj)) + { + return m_Info == other->m_Info; + } + + return false; +} + +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h new file mode 100644 index 0000000000..ee57ee920f --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_MAP_ALGORITHM_INFO_OBJECT_H +#define _MITK_MAP_ALGORITHM_INFO_OBJECT_H + +#include +#include + +#include + +#include "org_mitk_matchpoint_core_helper_Export.h" + +namespace mitk +{ + +/** + * @Class berry wrapper for a MatchPoint algorithm deployment info + * Used by mitk::MAPAlgorithmInfoSelection. + */ +class MITK_MATCHPOINT_CORE_HELPER_EXPORT MAPAlgorithmInfoObject : public berry::Object +{ + +public: + + berryObjectMacro(mitk::MAPAlgorithmInfoObject) + + MAPAlgorithmInfoObject(); + MAPAlgorithmInfoObject(::map::deployment::DLLInfo::ConstPointer info); + + const ::map::deployment::DLLInfo* GetInfo() const; + + bool operator==(const berry::Object* obj) const; + +private: + + ::map::deployment::DLLInfo::ConstPointer m_Info; + + +}; + +} + +#endif \ No newline at end of file diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.cpp b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.cpp new file mode 100644 index 0000000000..2ecaf7f034 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.cpp @@ -0,0 +1,112 @@ +/*=================================================================== + +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 "mitkMAPAlgorithmInfoSelection.h" + +#include "mitkMAPAlgorithmInfoObject.h" + +namespace mitk +{ + +MAPAlgorithmInfoSelection::MAPAlgorithmInfoSelection() : + m_Selection(new ContainerType()) +{ + +} + +MAPAlgorithmInfoSelection::MAPAlgorithmInfoSelection(AlgorithmInfoType::ConstPointer info) : + m_Selection(new ContainerType()) +{ + MAPAlgorithmInfoObject::Pointer obj(new MAPAlgorithmInfoObject(info)); + m_Selection->push_back(obj); +} + +MAPAlgorithmInfoSelection::MAPAlgorithmInfoSelection(const AlgorithmInfoVectorType& infos) : + m_Selection(new ContainerType()) +{ + for (AlgorithmInfoVectorType::const_iterator i = infos.begin(); i != infos.end(); ++i) + { + MAPAlgorithmInfoObject::Pointer obj(new MAPAlgorithmInfoObject(*i)); + m_Selection->push_back(obj); + } +} + +berry::Object::Pointer MAPAlgorithmInfoSelection::GetFirstElement() const +{ + if (m_Selection->empty()) + return berry::Object::Pointer(); + + return *(m_Selection->begin()); +} + +berry::IStructuredSelection::iterator MAPAlgorithmInfoSelection::Begin() const +{ + return m_Selection->begin(); +} + +berry::IStructuredSelection::iterator MAPAlgorithmInfoSelection::End() const +{ + return m_Selection->end(); +} + +int MAPAlgorithmInfoSelection::Size() const +{ + return m_Selection->size(); +} + +berry::IStructuredSelection::ContainerType::Pointer MAPAlgorithmInfoSelection::ToVector() const +{ + return m_Selection; +} + +MAPAlgorithmInfoSelection::AlgorithmInfoVectorType MAPAlgorithmInfoSelection::GetSelectedAlgorithmInfo() const +{ + AlgorithmInfoVectorType selectedInfos; + if(IsEmpty()) + return selectedInfos; + + MAPAlgorithmInfoObject::Pointer infoObject; + AlgorithmInfoType::ConstPointer info; + + for(iterator it = Begin(); it != End(); ++it) + { + infoObject = it->Cast(); + if(infoObject.IsNotNull()) + { + info = infoObject->GetInfo(); + if(info.IsNotNull()) + selectedInfos.push_back(info); + } + } + return selectedInfos; +} + +bool MAPAlgorithmInfoSelection::IsEmpty() const +{ + return m_Selection->empty(); +} + +bool MAPAlgorithmInfoSelection::operator==(const berry::Object* obj) const +{ + if (const berry::IStructuredSelection* other = dynamic_cast(obj)) + { + return m_Selection == other->ToVector(); + } + + return false; +} + +} diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h new file mode 100644 index 0000000000..223ff730b2 --- /dev/null +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h @@ -0,0 +1,72 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_MAP_ALGORITHM_INFO_SELECTION_H +#define _MITK_MAP_ALGORITHM_INFO_SELECTION_H + +#include + +#include + +#include "org_mitk_matchpoint_core_helper_Export.h" + + +namespace mitk { + +/** + * @class Used by plugins to communicate selections of deployed algorithms + * E.G. used by the algorithm browser to inform about the currently selected algorithm. + */ +class MITK_MATCHPOINT_CORE_HELPER_EXPORT MAPAlgorithmInfoSelection : public virtual berry::IStructuredSelection +{ + +public: + + berryObjectMacro(MAPAlgorithmInfoSelection); + + typedef ::map::deployment::DLLInfo AlgorithmInfoType; + typedef std::vector AlgorithmInfoVectorType; + + MAPAlgorithmInfoSelection(); + MAPAlgorithmInfoSelection(AlgorithmInfoType::ConstPointer info); + MAPAlgorithmInfoSelection(const AlgorithmInfoVectorType& infos); + + virtual Object::Pointer GetFirstElement() const; + virtual iterator Begin() const; + virtual iterator End() const; + + virtual int Size() const; + + virtual ContainerType::Pointer ToVector() const; + + AlgorithmInfoVectorType GetSelectedAlgorithmInfo() const; + + /** + * @see berry::ISelection::IsEmpty() + */ + bool IsEmpty() const; + + bool operator==(const berry::Object* obj) const; + +protected: + + ContainerType::Pointer m_Selection; +}; + +} + + +#endif \ No newline at end of file