diff --git a/CMake/PackageDepends/MITK_ITK_Config.cmake b/CMake/PackageDepends/MITK_ITK_Config.cmake index 04f5844e63..e5fd53358f 100644 --- a/CMake/PackageDepends/MITK_ITK_Config.cmake +++ b/CMake/PackageDepends/MITK_ITK_Config.cmake @@ -1,17 +1,19 @@ find_package(ITK REQUIRED) # # for some reason this does not work on windows, probably an ITK bug # ITK_BUILD_SHARED is OFF even in shared library builds # #if(ITK_FOUND AND NOT ITK_BUILD_SHARED) # message(FATAL_ERROR "MITK only supports a ITK which was built with shared libraries. Turn on BUILD_SHARED_LIBS in your ITK config.") #endif(ITK_FOUND AND NOT ITK_BUILD_SHARED) +set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1) + include(${ITK_USE_FILE}) list(APPEND ALL_LIBRARIES ${ITK_LIBRARIES}) list(APPEND ALL_INCLUDE_DIRECTORIES ${ITK_INCLUDE_DIRS}) find_package(GDCM PATHS ${ITK_GDCM_DIR} REQUIRED) list(APPEND ALL_INCLUDE_DIRECTORIES ${GDCM_INCLUDE_DIRS}) list(APPEND ALL_LIBRARIES ${GDCM_LIBRARIES}) include(${GDCM_USE_FILE}) diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake index 7bc94f3db7..57cd030b92 100644 --- a/CMakeExternals/CTK.cmake +++ b/CMakeExternals/CTK.cmake @@ -1,92 +1,92 @@ #----------------------------------------------------------------------------- # CTK #----------------------------------------------------------------------------- if(MITK_USE_CTK) # Sanity checks if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR}) message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj CTK) set(proj_DEPENDENCIES ) set(CTK_DEPENDS ${proj}) if(NOT DEFINED CTK_DIR) - set(revision_tag fef76cef) + set(revision_tag 71c756a3) #IF(${proj}_REVISION_TAG) # SET(revision_tag ${${proj}_REVISION_TAG}) #ENDIF() set(ctk_optional_cache_args ) if(MITK_USE_Python) list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=ON -DCTK_ENABLE_Python_Wrapping:BOOL=ON -DCTK_APP_ctkSimplePythonShell:BOOL=ON -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} ) else() list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF -DCTK_ENABLE_Python_Wrapping:BOOL=OFF -DCTK_APP_ctkSimplePythonShell:BOOL=OFF ) endif() if(MITK_USE_DCMTK) list(APPEND ctk_optional_cache_args -DDCMTK_DIR:PATH=${DCMTK_DIR} ) list(APPEND proj_DEPENDENCIES DCMTK) else() list(APPEND ctk_optional_cache_args -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz ) endif() FOREACH(type RUNTIME ARCHIVE LIBRARY) IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) ENDIF() ENDFOREACH() ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz - URL_MD5 4d001d855cc3f722827a6cd95bfb7d9c + URL_MD5 25c219f2d881119312b8cd699b385259 UPDATE_COMMAND "" INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${ctk_optional_cache_args} -DDESIRED_QT_VERSION:STRING=4 -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} -DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON -DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON -DCTK_LIB_PluginFramework:BOOL=ON -DCTK_LIB_DICOM/Widgets:BOOL=ON -DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON -DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON -DCTK_USE_GIT_PROTOCOL:BOOL=OFF -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz DEPENDS ${proj_DEPENDENCIES} ) set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif() diff --git a/CMakeExternals/PatchSOFA-rev9479.cmake b/CMakeExternals/PatchSOFA-rev9479.cmake index 63ebc1be58..e41b2f00c4 100644 --- a/CMakeExternals/PatchSOFA-rev9479.cmake +++ b/CMakeExternals/PatchSOFA-rev9479.cmake @@ -1,72 +1,76 @@ file(STRINGS "cmake/preBuildConfig.cmake" preBuildConfig_cmake NEWLINE_CONSUME) string(REPLACE "DEBUG \"\${SOFA_BIN_DIR}" "DEBUG \"\${SOFA_BIN_DIR}/Debug" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "RELEASE \"\${SOFA_BIN_DIR}" "RELEASE \"\${SOFA_BIN_DIR}/Release" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "RELWITHDEBINFO \"\${SOFA_BIN_DIR}" "RELWITHDEBINFO \"\${SOFA_BIN_DIR}/RelWithDebInfo" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "MINSIZEREL \"\${SOFA_BIN_DIR}" "MINSIZEREL \"\${SOFA_BIN_DIR}/MinSizeRel" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "DEBUG \"\${SOFA_LIB_DIR}" "DEBUG \"\${SOFA_LIB_DIR}/Debug" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "RELEASE \"\${SOFA_LIB_DIR}" "RELEASE \"\${SOFA_LIB_DIR}/Release" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "RELWITHDEBINFO \"\${SOFA_LIB_DIR}" "RELWITHDEBINFO \"\${SOFA_LIB_DIR}/RelWithDebInfo" preBuildConfig_cmake "${preBuildConfig_cmake}") string(REPLACE "MINSIZEREL \"\${SOFA_LIB_DIR}" "MINSIZEREL \"\${SOFA_LIB_DIR}/MinSizeRel" preBuildConfig_cmake "${preBuildConfig_cmake}") file(WRITE "cmake/preBuildConfig.cmake" "${preBuildConfig_cmake}") +file(STRINGS "CMakeLists.txt" CMakeLists_txt NEWLINE_CONSUME) +string(REPLACE "2.8.8" "2.8.5" CMakeLists_txt "${CMakeLists_txt}") +file(WRITE "CMakeLists.txt" "${CMakeLists_txt}") + file(APPEND "CMakeLists.txt" "\n\nconfigure_file(SOFAConfig.cmake.in SOFAConfig.cmake @ONLY)") file(WRITE "SOFAConfig.cmake.in" -"add_definitions(-DSOFA_HAVE_EIGEN2;-DSOFA_XML_PARSER_TINYXML;-DTIXML_USE_STL;-DMINI_FLOWVR) +"add_definitions(-DSOFA_NO_OPENGL;-DSOFA_HAVE_EIGEN2;-DSOFA_XML_PARSER_TINYXML;-DTIXML_USE_STL;-DMINI_FLOWVR) set(SOFA_INCLUDE_DIRS \"@SOFA_EXTLIBS_DIR@/eigen-3.1.1;@SOFA_EXTLIBS_DIR@/miniBoost;@SOFA_EXTLIBS_DIR@/miniFlowVR/include;@SOFA_EXTLIBS_DIR@/newmat;@SOFA_EXTLIBS_DIR@/tinyxml;@SOFA_SRC_DIR@/framework;@SOFA_SRC_DIR@/modules\") set(SOFA_LIBRARY_DIRS \"@SOFA_LIB_DIR@\") set(SOFA_LIBRARIES debug SofaBaseAnimationLoop_1_0d optimized SofaBaseAnimationLoop_1_0 debug SofaBaseCollision_1_0d optimized SofaBaseCollision_1_0 debug SofaBaseLinearSolver_1_0d optimized SofaBaseLinearSolver_1_0 debug SofaBaseMechanics_1_0d optimized SofaBaseMechanics_1_0 debug SofaBaseTopology_1_0d optimized SofaBaseTopology_1_0 debug SofaBaseVisual_1_0d optimized SofaBaseVisual_1_0 debug SofaBoundaryCondition_1_0d optimized SofaBoundaryCondition_1_0 debug SofaComponentAdvanced_1_0d optimized SofaComponentAdvanced_1_0 debug SofaComponentBase_1_0d optimized SofaComponentBase_1_0 debug SofaComponentCommon_1_0d optimized SofaComponentCommon_1_0 debug SofaComponentGeneral_1_0d optimized SofaComponentGeneral_1_0 debug SofaComponentMain_1_0d optimized SofaComponentMain_1_0 debug SofaComponentMisc_1_0d optimized SofaComponentMisc_1_0 debug SofaConstraint_1_0d optimized SofaConstraint_1_0 debug SofaCore_1_0d optimized SofaCore_1_0 debug SofaDefaultType_1_0d optimized SofaDefaultType_1_0 debug SofaDeformable_1_0d optimized SofaDeformable_1_0 debug SofaDenseSolver_1_0d optimized SofaDenseSolver_1_0 debug SofaEigen2Solver_1_0d optimized SofaEigen2Solver_1_0 debug SofaEngine_1_0d optimized SofaEngine_1_0 debug SofaEulerianFluid_1_0d optimized SofaEulerianFluid_1_0 debug SofaExplicitOdeSolver_1_0d optimized SofaExplicitOdeSolver_1_0 debug SofaExporter_1_0d optimized SofaExporter_1_0 debug SofaGraphComponent_1_0d optimized SofaGraphComponent_1_0 debug SofaHaptics_1_0d optimized SofaHaptics_1_0 debug SofaHelper_1_0d optimized SofaHelper_1_0 debug SofaImplicitOdeSolver_1_0d optimized SofaImplicitOdeSolver_1_0 debug SofaLoader_1_0d optimized SofaLoader_1_0 debug SofaMeshCollision_1_0d optimized SofaMeshCollision_1_0 debug SofaMisc_1_0d optimized SofaMisc_1_0 debug SofaMiscCollision_1_0d optimized SofaMiscCollision_1_0 debug SofaMiscEngine_1_0d optimized SofaMiscEngine_1_0 debug SofaMiscFem_1_0d optimized SofaMiscFem_1_0 debug SofaMiscForceField_1_0d optimized SofaMiscForceField_1_0 debug SofaMiscMapping_1_0d optimized SofaMiscMapping_1_0 debug SofaMiscSolver_1_0d optimized SofaMiscSolver_1_0 debug SofaMiscTopology_1_0d optimized SofaMiscTopology_1_0 debug SofaNonUniformFem_1_0d optimized SofaNonUniformFem_1_0 debug SofaObjectInteraction_1_0d optimized SofaObjectInteraction_1_0 debug SofaPreconditioner_1_0d optimized SofaPreconditioner_1_0 debug SofaRigid_1_0d optimized SofaRigid_1_0 debug SofaSimpleFem_1_0d optimized SofaSimpleFem_1_0 debug SofaSimulationCommon_1_0d optimized SofaSimulationCommon_1_0 debug SofaSimulationTree_1_0d optimized SofaSimulationTree_1_0 debug SofaSphFluid_1_0d optimized SofaSphFluid_1_0 debug SofaTopologyMapping_1_0d optimized SofaTopologyMapping_1_0 debug SofaUserInteraction_1_0d optimized SofaUserInteraction_1_0 debug SofaValidation_1_0d optimized SofaValidation_1_0 debug SofaVolumetricData_1_0d optimized SofaVolumetricData_1_0 debug tinyxml_1_0d optimized tinyxml_1_0 )") diff --git a/CMakeLists.txt b/CMakeLists.txt index 26345d1be3..f965f4abda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,982 +1,974 @@ if(APPLE) # With XCode 4.3, the SDK location changed. Older CMake # versions are not able to find it. cmake_minimum_required(VERSION 2.8.8) else() cmake_minimum_required(VERSION 2.8.5) endif() #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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) 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 43) # _src_dir_length_max - strlen(ITK-src) 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() #----------------------------------------------------------------------------- # See http://cmake.org/cmake/help/cmake-2-8-docs.html#section_Policies for details #----------------------------------------------------------------------------- set(project_policies CMP0001 # NEW: CMAKE_BACKWARDS_COMPATIBILITY should no longer be used. CMP0002 # NEW: Logical target names must be globally unique. CMP0003 # NEW: Libraries linked via full path no longer produce linker search paths. CMP0004 # NEW: Libraries linked may NOT have leading or trailing whitespace. CMP0005 # NEW: Preprocessor definition values are now escaped automatically. CMP0006 # NEW: Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION. CMP0007 # NEW: List command no longer ignores empty elements. CMP0008 # NEW: Libraries linked by full-path must have a valid library file name. CMP0009 # NEW: FILE GLOB_RECURSE calls should not follow symlinks by default. CMP0010 # NEW: Bad variable reference syntax is an error. CMP0011 # NEW: Included scripts do automatic cmake_policy PUSH and POP. CMP0012 # NEW: if() recognizes numbers and boolean constants. CMP0013 # NEW: Duplicate binary directories are not allowed. CMP0014 # NEW: Input directories must have CMakeLists.txt ) foreach(policy ${project_policies}) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() endforeach() #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(CMAKE_MODULE_PATH ${MITK_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(mitkMacroEmptyExternalProject) include(mitkFunctionGenerateProjectXml) include(mitkFunctionSuppressWarnings) SUPPRESS_VC_DEPRECATED_WARNINGS() #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- foreach(type LIBRARY RUNTIME ARCHIVE) # Make sure the directory exists if(DEFINED 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_USE_SUPERBUILD) set(output_dir ${MITK_BINARY_DIR}/bin) if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_BINARY_DIR}/MITK-build/bin) endif() else() if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(output_dir ${MITK_BINARY_DIR}/bin) else() set(output_dir ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) endif() endif() set(CMAKE_${type}_OUTPUT_DIRECTORY ${output_dir} CACHE INTERNAL "Single output directory for building all libraries.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Additional MITK Options (also shown during superbuild) #----------------------------------------------------------------------------- option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) set(MITK_BUILD_TUTORIAL OFF CACHE INTERNAL "Deprecated! Use MITK_BUILD_EXAMPLES instead!") option(MITK_BUILD_EXAMPLES "Build the MITK Examples" ${MITK_BUILD_TUTORIAL}) option(MITK_USE_Boost "Use the Boost C++ library" OFF) option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_BLUEBERRY}) option(MITK_USE_QT "Use Nokia's Qt library" ${MITK_USE_CTK}) option(MITK_USE_DCMTK "EXPERIMENTAL, superbuild only: Use DCMTK in MITK" ${MITK_USE_CTK}) option(MITK_DCMTK_BUILD_SHARED_LIBS "EXPERIMENTAL, superbuild only: build DCMTK as shared libs" OFF) option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF) option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF) option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF) option(MITK_USE_Python "Use Python wrapping in MITK" OFF) set(MITK_USE_CableSwig ${MITK_USE_Python}) if(MITK_USE_Python) FIND_PACKAGE(PythonLibs REQUIRED) FIND_PACKAGE(PythonInterp REQUIRED) endif() mark_as_advanced(MITK_BUILD_ALL_APPS MITK_USE_CTK MITK_USE_DCMTK ) if(MITK_USE_Boost) 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") 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() if(MITK_USE_CTK) if(NOT MITK_USE_QT) message("Forcing MITK_USE_QT to ON because of MITK_USE_CTK") set(MITK_USE_QT ON CACHE BOOL "Use Nokia's Qt library in MITK" FORCE) endif() if(NOT MITK_USE_DCMTK) message("Setting MITK_USE_DCMTK to ON because DCMTK needs to be build for CTK") set(MITK_USE_DCMTK ON CACHE BOOL "Use DCMTK in MITK" FORCE) endif() endif() if(MITK_USE_QT) # find the package at the very beginning, so that QT4_FOUND is available find_package(Qt4 4.6.2 REQUIRED) endif() -if(MITK_USE_SOFA) - # set(SOFA_CMAKE_VERSION 2.8.8) - # if(${CMAKE_VERSION} VERSION_LESS ${SOFA_CMAKE_VERSION}) - set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE) - # message(WARNING "Switched off MITK_USE_SOFA\n Minimum required CMake version: ${SOFA_CMAKE_VERSION}\n Installed CMake version: ${CMAKE_VERSION}") - # endif() -endif() - # 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_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) if(MITK_USE_BLUEBERRY) list(APPEND CTEST_PROJECT_SUBPROJECTS BlueBerry) endif() 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") return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(CheckCXXSourceCompiles) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionGetGccVersion) include(MacroParseArguments) include(mitkFunctionSuppressWarnings) # includes several functions include(mitkFunctionOrganizeSources) include(mitkFunctionGetVersion) include(mitkFunctionGetVersionDescription) include(mitkFunctionCreateWindowsBatchScript) include(mitkFunctionInstallProvisioningFiles) include(mitkFunctionInstallAutoLoadModules) include(mitkFunctionCompileSnippets) include(mitkMacroCreateModuleConf) include(mitkMacroCreateModule) include(mitkMacroCheckModule) include(mitkMacroCreateModuleTests) include(mitkFunctionAddCustomModuleTest) include(mitkMacroUseModule) include(mitkMacroMultiplexPicType) include(mitkMacroInstall) include(mitkMacroInstallHelperApp) include(mitkMacroInstallTargets) include(mitkMacroGenerateToolsLibrary) include(mitkMacroGetLinuxDistribution) #----------------------------------------------------------------------------- # Prerequesites #----------------------------------------------------------------------------- find_package(ITK REQUIRED) find_package(VTK REQUIRED) find_package(GDCM PATHS ${ITK_GDCM_DIR} REQUIRED) include(${GDCM_USE_FILE}) #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK) mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK) #----------------------------------------------------------------------------- # 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} ${app_name}) endif() endforeach() endif() #----------------------------------------------------------------------------- # Set symbol visibility Flags #----------------------------------------------------------------------------- # MinGW does not export all symbols automatically, so no need to set flags if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW) set(VISIBILITY_CXX_FLAGS ) #"-fvisibility=hidden -fvisibility-inlines-hidden") 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 "${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}") set(MITK_CXX_FLAGS_DEBUG ) set(MITK_CXX_FLAGS_RELEASE ) set(MITK_EXE_LINKER_FLAGS ) set(MITK_SHARED_LINKER_FLAGS ) include(mitkSetupC++0xVariables) if(WIN32) set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN") endif() if(NOT MSVC_VERSION) foreach(_flag -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Wno-error=gnu -Woverloaded-virtual -Wstrict-null-sentinel #-Wold-style-cast #-Wsign-promo -fdiagnostics-show-option ) mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS) endforeach() endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS) mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS) if(MITK_USE_C++0x) mitkFunctionCheckCompilerFlags("-std=c++0x" MITK_CXX_FLAGS) endif() mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) # With older version of gcc supporting the flag -fstack-protector-all, an extra dependency to libssp.so # is introduced. If gcc is smaller than 4.4.0 and the build type is Release let's not include the flag. # Doing so should allow to build package made for distribution using older linux distro. if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0")) mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS) endif() 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 "-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}) #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() include(CTest) mark_as_advanced(TCL_TCLSH DART_ROOT) option(MITK_ENABLE_GUI_TESTING OFF "Enable the MITK GUI tests") # Setup file for setting custom ctest vars configure_file( CMake/CTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @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() #----------------------------------------------------------------------------- # Compile Utilities and set-up MITK variables #----------------------------------------------------------------------------- include(mitkSetupVariables) #----------------------------------------------------------------------------- # Cleanup #----------------------------------------------------------------------------- file(GLOB _MODULES_CONF_FILES ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake) if(_MODULES_CONF_FILES) file(REMOVE ${_MODULES_CONF_FILES}) endif() add_subdirectory(Utilities) if(MITK_USE_BLUEBERRY) # We need to hack a little bit because MITK applications may need # to enable certain BlueBerry plug-ins. However, these plug-ins # are validated separately from the MITK plug-ins and know nothing # about potential MITK plug-in dependencies of the applications. Hence # we cannot pass the MITK application list to the BlueBerry # ctkMacroSetupPlugins call but need to extract the BlueBerry dependencies # from the applications and set them explicitly. include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") 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) # check if the application is enabled and if target_libraries.cmake exists if((${option_name} OR MITK_BUILD_ALL_APPS) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake") foreach(_target_dep ${target_libraries}) if(_target_dep MATCHES org_blueberry_) string(REPLACE _ . _app_bb_dep ${_target_dep}) # explicitly set the build option for the BlueBerry plug-in set(BLUEBERRY_BUILD_${_app_bb_dep} ON CACHE BOOL "Build the ${_app_bb_dep} plug-in") endif() endforeach() endif() endforeach() set(mbilog_DIR "${mbilog_BINARY_DIR}") if(MITK_BUILD_ALL_PLUGINS) set(BLUEBERRY_BUILD_ALL_PLUGINS ON) endif() set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/) add_subdirectory(BlueBerry) set(BlueBerry_DIR ${CMAKE_CURRENT_BINARY_DIR}/BlueBerry CACHE PATH "The directory containing a CMake configuration file for BlueBerry" FORCE) include(mitkMacroCreateCTKPlugin) 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}") if(MITK_USE_QT) add_definitions(-DQWT_DLL) endif() #----------------------------------------------------------------------------- # 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 #----------------------------------------------------------------------------- link_directories(${MITK_LINK_DIRECTORIES}) add_subdirectory(Core) include(${CMAKE_CURRENT_BINARY_DIR}/Core/Code/CppMicroServices/CppMicroServicesConfig.cmake) add_subdirectory(Modules) if(MITK_USE_BLUEBERRY) find_package(BlueBerry REQUIRED) set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins) # Plug-in testing (needs some work to be enabled again) if(BUILD_TESTING) include(berryTestingHelpers) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/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() set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake") set(mitk_plugins_fullpath ) foreach(mitk_plugin ${MITK_EXT_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() # 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}) list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${mitk_app}") endforeach() ctkMacroSetupPlugins(${mitk_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) 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() # 11.3.13, change, muellerm: activate python bundle if python and blueberry is active if( MITK_USE_Python ) set(MITK_BUILD_org.mitk.gui.qt.python ON) endif() endif() # Construct a list of paths containing runtime directories # for MITK applications on Windows set(MITK_RUNTIME_PATH "${VTK_LIBRARY_DIRS}/%VS_BUILD_TYPE%;${ITK_DIR}/bin/%VS_BUILD_TYPE%;${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/%VS_BUILD_TYPE%" ) if(QT4_FOUND) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${QT_LIBRARY_DIR}/../bin") endif() if(MITK_USE_BLUEBERRY) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${CTK_RUNTIME_LIBRARY_DIRS}/%VS_BUILD_TYPE%") if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}/%VS_BUILD_TYPE%") else() set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}/%VS_BUILD_TYPE%") endif() else() set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins/%VS_BUILD_TYPE%") endif() endif() if(GDCM_DIR) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${GDCM_DIR}/bin/%VS_BUILD_TYPE%") endif() if(OpenCV_DIR) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${OpenCV_DIR}/bin/%VS_BUILD_TYPE%") endif() if(SOFA_DIR) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${SOFA_DIR}/bin/%VS_BUILD_TYPE%") endif() # DCMTK is statically build #if(DCMTK_DIR) # set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${DCMTK_DIR}/bin/%VS_BUILD_TYPE%") #endif() if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${Boost_LIBRARY_DIRS}") endif() #----------------------------------------------------------------------------- # Python Wrapping #----------------------------------------------------------------------------- option(MITK_USE_Python "Build Python integration for MITK (requires CableSwig)." OFF) if(MITK_USE_Python) set(MITK_RUNTIME_PATH "${MITK_RUNTIME_PATH};${CTK_PYTHONQT_INSTALL_DIR}/bin") endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- add_subdirectory(Documentation) #----------------------------------------------------------------------------- # 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) # 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 "${target_dir}") 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 #----------------------------------------------------------------------------- # This is for installation support of external projects depending on # MITK plugins and modules. The export file should not be used for linking to MITK # libraries without using LINK_DIRECTORIES, since the exports are incomplete # yet (depending libraries are not exported). 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() endforeach() 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) set(VISIBILITY_AVAILABLE 0) set(visibility_test_flag "") mitkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_test_flag) if(visibility_test_flag) # The compiler understands -fvisiblity=hidden (probably gcc >= 4 or Clang) set(VISIBILITY_AVAILABLE 1) endif() configure_file(mitkExportMacros.h.in ${MITK_BINARY_DIR}/mitkExportMacros.h) configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) set(VECMATH_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/vecmath) set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc) set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities) file(GLOB _MODULES_CONF_FILES RELATIVE ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME} ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake) set(MITK_MODULE_NAMES) foreach(_module ${_MODULES_CONF_FILES}) string(REPLACE Config.cmake "" _module_name ${_module}) list(APPEND MITK_MODULE_NAMES ${_module_name}) endforeach() configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY) # 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") 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() diff --git a/Core/Code/Interactions/mitkEventConfig.cpp b/Core/Code/Interactions/mitkEventConfig.cpp index aeaaa7fd6e..ad0c4fa87e 100755 --- a/Core/Code/Interactions/mitkEventConfig.cpp +++ b/Core/Code/Interactions/mitkEventConfig.cpp @@ -1,393 +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. ===================================================================*/ #include "mitkEventConfig.h" #include "mitkEventFactory.h" #include "mitkInteractionEvent.h" #include "mitkInternalEvent.h" #include "mitkInteractionKeyEvent.h" #include "mitkInteractionEventConst.h" // VTK #include #include // us #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleResource.h" #include "mitkModuleResourceStream.h" namespace mitk { class EventConfigXMLParser : public vtkXMLParser { public: EventConfigXMLParser(EventConfigPrivate* d); protected: /** * @brief Derived from XMLReader **/ void StartElement(const char* elementName, const char **atts); /** * @brief Derived from XMLReader **/ void EndElement(const char* elementName); std::string ReadXMLStringAttribute(const std::string& name, const char** atts); bool ReadXMLBooleanAttribute(const std::string& name, const char** atts); private: EventConfigPrivate* const d; }; struct EventConfigPrivate : public SharedData { EventConfigPrivate(); EventConfigPrivate(const EventConfigPrivate& other); struct EventMapping { std::string variantName; InteractionEvent::ConstPointer interactionEvent; }; /** * Checks if mapping with the same parameters already exists, if so, it is replaced, * else the new mapping added */ void InsertMapping(const EventMapping& mapping); /** * @brief List of all global properties of the config object. */ PropertyList::Pointer m_PropertyList; /** * @brief Temporal list of all prMousePressEventoperties of a Event. Used to parse an Input-Event and collect all parameters between the two * and tags. */ PropertyList::Pointer m_EventPropertyList; EventMapping m_CurrEventMapping; typedef std::list EventListType; /** * Stores InteractionEvents and their corresponding VariantName */ EventListType m_EventList; bool m_Errors; // use member, because of inheritance from vtkXMLParser we can't return a success value for parsing the file. EventConfigXMLParser m_XmlParser; }; } mitk::EventConfigPrivate::EventConfigPrivate() : m_PropertyList(PropertyList::New()) , m_Errors(false) , m_XmlParser(this) { // Avoid VTK warning: Trying to delete object with non-zero reference count. m_XmlParser.SetReferenceCount(0); } mitk::EventConfigPrivate::EventConfigPrivate(const EventConfigPrivate& other) : SharedData(other) , m_PropertyList(other.m_PropertyList->Clone()) , m_EventPropertyList(other.m_EventPropertyList->Clone()) , m_CurrEventMapping(other.m_CurrEventMapping) , m_EventList(other.m_EventList) , m_Errors(other.m_Errors) , m_XmlParser(this) { // Avoid VTK warning: Trying to delete object with non-zero reference count. m_XmlParser.SetReferenceCount(0); } void mitk::EventConfigPrivate::InsertMapping(const EventMapping& mapping) { for (EventListType::iterator it = m_EventList.begin(); it != m_EventList.end(); ++it) { if (*(it->interactionEvent) == *mapping.interactionEvent) { //MITK_INFO<< "Configuration overwritten:" << (*it).variantName; m_EventList.erase(it); break; } } m_EventList.push_back(mapping); } mitk::EventConfigXMLParser::EventConfigXMLParser(EventConfigPrivate *d) : d(d) { } void mitk::EventConfigXMLParser::StartElement(const char* elementName, const char **atts) { std::string name(elementName); - if (name == InteractionEventConst::xmlTagConfigRoot) + if (name == InteractionEventConst::xmlTagConfigRoot()) { // } - else if (name == InteractionEventConst::xmlTagParam) + else if (name == InteractionEventConst::xmlTagParam()) { - std::string name = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName, atts); - std::string value = ReadXMLStringAttribute(InteractionEventConst::xmlParameterValue, atts); + std::string name = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName(), atts); + std::string value = ReadXMLStringAttribute(InteractionEventConst::xmlParameterValue(), atts); d->m_PropertyList->SetStringProperty(name.c_str(), value.c_str()); } - else if (name == InteractionEventConst::xmlTagEventVariant) + else if (name == InteractionEventConst::xmlTagEventVariant()) { - std::string eventClass = ReadXMLStringAttribute(InteractionEventConst::xmlParameterEventClass, atts); - std::string eventVariant = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName, atts); + std::string eventClass = ReadXMLStringAttribute(InteractionEventConst::xmlParameterEventClass(), atts); + std::string eventVariant = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName(), atts); // New list in which all parameters are stored that are given within the tag d->m_EventPropertyList = PropertyList::New(); - d->m_EventPropertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass.c_str(), eventClass.c_str()); - d->m_EventPropertyList->SetStringProperty(InteractionEventConst::xmlParameterEventVariant.c_str(), eventVariant.c_str()); + d->m_EventPropertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), eventClass.c_str()); + d->m_EventPropertyList->SetStringProperty(InteractionEventConst::xmlParameterEventVariant().c_str(), eventVariant.c_str()); d->m_CurrEventMapping.variantName = eventVariant; } - else if (name == InteractionEventConst::xmlTagAttribute) + else if (name == InteractionEventConst::xmlTagAttribute()) { // Attributes that describe an Input Event, such as which MouseButton triggered the event,or which modifier keys are pressed - std::string name = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName, atts); - std::string value = ReadXMLStringAttribute(InteractionEventConst::xmlParameterValue, atts); + std::string name = ReadXMLStringAttribute(InteractionEventConst::xmlParameterName(), atts); + std::string value = ReadXMLStringAttribute(InteractionEventConst::xmlParameterValue(), atts); d->m_EventPropertyList->SetStringProperty(name.c_str(), value.c_str()); } } void mitk::EventConfigXMLParser::EndElement(const char* elementName) { std::string name(elementName); // At end of input section, all necessary infos are collected to created an interaction event. - if (name == InteractionEventConst::xmlTagEventVariant) + if (name == InteractionEventConst::xmlTagEventVariant()) { InteractionEvent::Pointer event = EventFactory::CreateEvent(d->m_EventPropertyList); if (event.IsNotNull()) { d->m_CurrEventMapping.interactionEvent = event; d->InsertMapping(d->m_CurrEventMapping); } else { MITK_WARN<< "EventConfig: Unknown Event-Type in config. Entry skipped: " << name; } } } std::string mitk::EventConfigXMLParser::ReadXMLStringAttribute(const std::string& name, const char** atts) { if (atts) { const char** attsIter = atts; while (*attsIter) { if (name == *attsIter) { attsIter++; return *attsIter; } attsIter += 2; } } return std::string(); } bool mitk::EventConfigXMLParser::ReadXMLBooleanAttribute(const std::string& name, const char** atts) { std::string s = ReadXMLStringAttribute(name, atts); std::transform(s.begin(), s.end(), s.begin(), ::toupper); return s == "TRUE"; } mitk::EventConfig::EventConfig() : d(new EventConfigPrivate) { } mitk::EventConfig::EventConfig(const EventConfig &other) : d(other.d) { } mitk::EventConfig::EventConfig(const std::string& filename, const Module* module) : d(new EventConfigPrivate) { if (module == NULL) { module = GetModuleContext()->GetModule(); } mitk::ModuleResource resource = module->GetResource("Interactions/" + filename); if (!resource.IsValid()) { MITK_ERROR << "Resource not valid. State machine pattern in module " << module->GetName() << " not found: /Interactions/" << filename; return; } EventConfig newConfig; mitk::ModuleResourceStream stream(resource); newConfig.d->m_XmlParser.SetStream(&stream); bool success = newConfig.d->m_XmlParser.Parse() && !newConfig.d->m_Errors; if (success) { *this = newConfig; } } mitk::EventConfig::EventConfig(std::istream &inputStream) : d(new EventConfigPrivate) { EventConfig newConfig; newConfig.d->m_XmlParser.SetStream(&inputStream); bool success = newConfig.d->m_XmlParser.Parse() && !newConfig.d->m_Errors; if (success) { *this = newConfig; } } mitk::EventConfig::EventConfig(const std::vector &configDescription) : d(new EventConfigPrivate) { std::vector::const_iterator it_end = configDescription.end(); for (std::vector::const_iterator it = configDescription.begin(); it != it_end; ++it) { InteractionEvent::Pointer event = EventFactory::CreateEvent(*it); if (event.IsNotNull()) { d->m_CurrEventMapping.interactionEvent = event; std::string eventVariant; - (*it)->GetStringProperty(InteractionEventConst::xmlTagEventVariant.c_str(), eventVariant); + (*it)->GetStringProperty(InteractionEventConst::xmlTagEventVariant().c_str(), eventVariant); d->m_CurrEventMapping.variantName = eventVariant; d->InsertMapping(d->m_CurrEventMapping); } else { MITK_WARN<< "EventConfig: Unknown Event-Type in config. When constructing from PropertyList."; } } } mitk::EventConfig& mitk::EventConfig::operator =(const mitk::EventConfig& other) { d = other.d; return *this; } mitk::EventConfig::~EventConfig() { } bool mitk::EventConfig::IsValid() const { return !d->m_EventList.empty(); } bool mitk::EventConfig::AddConfig(const std::string& fileName, const Module* module) { if (module == NULL) { module = GetModuleContext()->GetModule(); } mitk::ModuleResource resource = module->GetResource("Interactions/" + fileName); if (!resource.IsValid()) { MITK_ERROR << "Resource not valid. State machine pattern in module " << module->GetName() << " not found: /Interactions/" << fileName; return false; } EventConfig newConfig(*this); mitk::ModuleResourceStream stream(resource); newConfig.d->m_XmlParser.SetStream(&stream); bool success = newConfig.d->m_XmlParser.Parse() && !newConfig.d->m_Errors; if (success) { *this = newConfig; } return success; } bool mitk::EventConfig::AddConfig(const EventConfig& config) { if (!config.IsValid()) return false; d->m_PropertyList->ConcatenatePropertyList(config.d->m_PropertyList->Clone(), true); d->m_EventPropertyList = config.d->m_EventPropertyList->Clone(); d->m_CurrEventMapping = config.d->m_CurrEventMapping; d->InsertMapping(config.d->m_CurrEventMapping); return true; } mitk::PropertyList::Pointer mitk::EventConfig::GetAttributes() const { return d->m_PropertyList; } std::string mitk::EventConfig::GetMappedEvent(const EventType& interactionEvent) const { // internal events are excluded from mapping if (std::strcmp(interactionEvent->GetNameOfClass(), "InternalEvent") == 0) { InternalEvent* internalEvent = dynamic_cast(interactionEvent.GetPointer()); return internalEvent->GetSignalName(); } for (EventConfigPrivate::EventListType::const_iterator it = d->m_EventList.begin(); it != d->m_EventList.end(); ++it) { if (*(it->interactionEvent) == *interactionEvent) { return (*it).variantName; } } // if this part is reached, no mapping has been found, // so here we handle key events and map a key event to the string "Std" + letter/code // so "A" will be returned as "StdA" if (std::strcmp(interactionEvent->GetNameOfClass(), "InteractionKeyEvent") == 0) { InteractionKeyEvent* keyEvent = dynamic_cast(interactionEvent.GetPointer()); return ("Std" + keyEvent->GetKey()); } return ""; } void mitk::EventConfig::ClearConfig() { d->m_PropertyList->Clear(); d->m_EventPropertyList->Clear(); d->m_CurrEventMapping.variantName.clear(); d->m_CurrEventMapping.interactionEvent = NULL; d->m_EventList.clear(); d->m_Errors = false; } diff --git a/Core/Code/Interactions/mitkEventFactory.cpp b/Core/Code/Interactions/mitkEventFactory.cpp index ad26f7e4dc..31a2e08c7a 100755 --- a/Core/Code/Interactions/mitkEventFactory.cpp +++ b/Core/Code/Interactions/mitkEventFactory.cpp @@ -1,224 +1,224 @@ /*=================================================================== 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 "mitkEventFactory.h" #include #include #include #include #include #include #include #include #include #include #include namespace { std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } } mitk::InteractionEvent::Pointer mitk::EventFactory::CreateEvent(PropertyList::Pointer list) { // std::string eventClass, eventVariant; - list->GetStringProperty(InteractionEventConst::xmlParameterEventClass.c_str(), eventClass); - list->GetStringProperty(InteractionEventConst::xmlParameterEventVariant.c_str(), eventVariant); + list->GetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), eventClass); + list->GetStringProperty(InteractionEventConst::xmlParameterEventVariant().c_str(), eventVariant); // Query all possible attributes, if they are not present, set their default values. // Position Events & Key Events std::string strModifiers; InteractionEvent::ModifierKeys modifiers = InteractionEvent::NoKey; std::string strEventButton; InteractionEvent::MouseButtons eventButton = InteractionEvent::NoButton; std::string strButtonState; InteractionEvent::MouseButtons buttonState = InteractionEvent::NoButton; std::string strKey; std::string key; std::string strWheelDelta; int wheelDelta; std::string strSignalName = ""; Point2D pos; pos.Fill(0); // Parse modifier information - if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyModifier.c_str(), strModifiers)) + if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyModifier().c_str(), strModifiers)) { std::vector mods = split(strModifiers, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "CTRL") { modifiers = modifiers | InteractionEvent::ControlKey; } else if (*it == "ALT") { modifiers = modifiers | InteractionEvent::AltKey; } else if (*it == "SHIFT") { modifiers = modifiers | InteractionEvent::ShiftKey; } else { MITK_WARN<< "mitkEventFactory: Invalid event modifier in config file :" << (*it); } } } // Set EventButton - if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyEventButton.c_str(), strEventButton)) + if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyEventButton().c_str(), strEventButton)) { std::transform(strEventButton.begin(), strEventButton.end(), strEventButton.begin(), ::toupper); if (strEventButton == "MIDDLEMOUSEBUTTON") { eventButton = InteractionEvent::MiddleMouseButton; } else if (strEventButton == "LEFTMOUSEBUTTON") { eventButton = InteractionEvent::LeftMouseButton; } else if (strEventButton == "RIGHTMOUSEBUTTON") { eventButton = InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event button in config file: " << strEventButton; } } // Parse ButtonStates - if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyButtonState.c_str(), strButtonState)) + if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyButtonState().c_str(), strButtonState)) { std::vector mods = split(strButtonState, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "MIDDLEMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::MiddleMouseButton; } else if (*it == "LEFTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::LeftMouseButton; } else if (*it == "RIGHTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event buttonstate in config file:" << (*it); } } } // Key - if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyKey.c_str(), strKey)) + if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyKey().c_str(), strKey)) { key = ""; } else { key = strKey; } // WheelDelta - if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyScrollDirection.c_str(), strWheelDelta)) + if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyScrollDirection().c_str(), strWheelDelta)) { wheelDelta = 0; } else { std::transform(strWheelDelta.begin(), strWheelDelta.end(), strWheelDelta.begin(), ::toupper); if (strWheelDelta == "DOWN") { wheelDelta = -1; } else { wheelDelta = 1; } } // Internal Signals Name - list->GetStringProperty(InteractionEventConst::xmlEventPropertySignalName.c_str(), strSignalName); + list->GetStringProperty(InteractionEventConst::xmlEventPropertySignalName().c_str(), strSignalName); /* * Here the objects are created */ mitk::InteractionEvent::Pointer event; std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); if (eventClass == "MOUSEPRESSEVENT") { // buttonstates incorporate the event button (as in Qt) buttonState = buttonState | eventButton; event = MousePressEvent::New(NULL, pos, buttonState, modifiers, eventButton); } else if (eventClass == "MOUSEMOVEEVENT") { event = MouseMoveEvent::New(NULL, pos, buttonState, modifiers); } else if (eventClass == "MOUSERELEASEEVENT") { event = MouseReleaseEvent::New(NULL, pos, buttonState, modifiers, eventButton); } else if (eventClass == "INTERACTIONKEYEVENT") { event = InteractionKeyEvent::New(NULL, key, modifiers); } else if (eventClass == "MOUSEWHEELEVENT") { event = MouseWheelEvent::New(NULL, pos, buttonState, modifiers, wheelDelta); } else if (eventClass == "INTERACTIONPOSITIONEVENT") { event = InteractionPositionEvent::New(NULL, pos); } else if (eventClass == "INTERNALEVENT") { event = InternalEvent::New(NULL, NULL, strSignalName); } else if (eventClass == "INTERACTIONEVENT") { event = InteractionEvent::New(NULL); } if (event.IsNull()) { MITK_WARN<< "Event couldn't be constructed. Please check your StateMachine patterns and config files\n for the following event class, which is not valid: " << eventClass; return NULL; } return event; } diff --git a/Core/Code/Interactions/mitkInteractionEventConst.cpp b/Core/Code/Interactions/mitkInteractionEventConst.cpp index 35fb858ed3..810d1377af 100644 --- a/Core/Code/Interactions/mitkInteractionEventConst.cpp +++ b/Core/Code/Interactions/mitkInteractionEventConst.cpp @@ -1,41 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkInteractionEventConst.h" namespace mitk { -// XML Tags -const std::string InteractionEventConst::xmlTagConfigRoot = "config"; -const std::string InteractionEventConst::xmlTagParam = "param"; -const std::string InteractionEventConst::xmlTagEventVariant = "event_variant"; -const std::string InteractionEventConst::xmlTagAttribute = "attribute"; - -// XML Param -const std::string InteractionEventConst::xmlParameterName = "name"; -const std::string InteractionEventConst::xmlParameterValue = "value"; -const std::string InteractionEventConst::xmlParameterEventVariant = "event_variant"; -const std::string InteractionEventConst::xmlParameterEventClass = "class"; - -// Event Description -const std::string InteractionEventConst::xmlEventPropertyModifier = "Modifiers"; -const std::string InteractionEventConst::xmlEventPropertyEventButton = "EventButton"; -const std::string InteractionEventConst::xmlEventPropertyButtonState = "ButtonState"; -const std::string InteractionEventConst::xmlEventPropertyKey = "Key"; -const std::string InteractionEventConst::xmlEventPropertyScrollDirection = "ScrollDirection"; -const std::string InteractionEventConst::xmlEventPropertySignalName = "SignalName"; +const std::string InteractionEventConst::xmlTagConfigRoot() +{ + static const std::string xmlTagConfigRoot = "config"; + return xmlTagConfigRoot; +} + +const std::string InteractionEventConst::xmlTagParam() +{ + static const std::string xmlTagParam = "param"; + return xmlTagParam; + +} + +const std::string InteractionEventConst::xmlTagEventVariant() +{ + static const std::string xmlTagEventVariant = "event_variant"; + return xmlTagEventVariant; +} + +const std::string InteractionEventConst::xmlTagAttribute() +{ + static const std::string xmlTagAttribute = "attribute"; + return xmlTagAttribute; +} + +const std::string InteractionEventConst::xmlParameterName() +{ + static const std::string xmlParameterName = "name"; + return xmlParameterName; +} + +const std::string InteractionEventConst::xmlParameterValue() +{ + static const std::string xmlParameterValue = "value"; + return xmlParameterValue; +} + +const std::string InteractionEventConst::xmlParameterEventVariant() +{ + static const std::string xmlParameterEventVariant = "event_variant"; + return xmlParameterEventVariant; +} + +const std::string InteractionEventConst::xmlParameterEventClass() +{ + static const std::string xmlParameterEventClass = "class"; + return xmlParameterEventClass; +} + +const std::string InteractionEventConst::xmlEventPropertyModifier() +{ + static const std::string xmlEventPropertyModifier = "Modifiers"; + return xmlEventPropertyModifier; +} + +const std::string InteractionEventConst::xmlEventPropertyEventButton() +{ + static const std::string xmlEventPropertyEventButton = "EventButton"; + return xmlEventPropertyEventButton; +} + +const std::string InteractionEventConst::xmlEventPropertyButtonState() +{ + static const std::string xmlEventPropertyButtonState = "ButtonState"; + return xmlEventPropertyButtonState; +} + +const std::string InteractionEventConst::xmlEventPropertyKey() +{ + static const std::string xmlEventPropertyKey = "Key"; + return xmlEventPropertyKey; +} + +const std::string InteractionEventConst::xmlEventPropertyScrollDirection() +{ + static const std::string xmlEventPropertyScrollDirection = "ScrollDirection"; + return xmlEventPropertyScrollDirection; +} + +const std::string InteractionEventConst::xmlEventPropertySignalName() +{ + static const std::string xmlEventPropertySignalName = "SignalName"; + return xmlEventPropertySignalName; +} + } diff --git a/Core/Code/Interactions/mitkInteractionEventConst.h b/Core/Code/Interactions/mitkInteractionEventConst.h index 37ef831324..fea72b994c 100644 --- a/Core/Code/Interactions/mitkInteractionEventConst.h +++ b/Core/Code/Interactions/mitkInteractionEventConst.h @@ -1,54 +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 MITKINTERACTEVENTCONST_H #define MITKINTERACTEVENTCONST_H #include #include namespace mitk { /** * @brief Constants to describe Mouse Events and special Key Events. */ struct MITK_CORE_EXPORT InteractionEventConst { // XML Tags - static const std::string xmlTagConfigRoot; // = "config"; - static const std::string xmlTagParam; // = "param"; - static const std::string xmlTagEventVariant; // = "event_variant"; - static const std::string xmlTagAttribute; // = "attribute"; + static const std::string xmlTagConfigRoot(); // = "config"; + static const std::string xmlTagParam(); // = "param"; + static const std::string xmlTagEventVariant(); // = "event_variant"; + static const std::string xmlTagAttribute(); // = "attribute"; // XML Param - static const std::string xmlParameterName; // = "name"; - static const std::string xmlParameterValue; // = "value"; - static const std::string xmlParameterEventVariant; // = "event_variant"; - static const std::string xmlParameterEventClass; // = "class"; + static const std::string xmlParameterName(); // = "name"; + static const std::string xmlParameterValue(); // = "value"; + static const std::string xmlParameterEventVariant(); // = "event_variant"; + static const std::string xmlParameterEventClass(); // = "class"; // Event Description - static const std::string xmlEventPropertyModifier; // = "Modifiers"; - static const std::string xmlEventPropertyEventButton; // = "EventButton"; - static const std::string xmlEventPropertyButtonState; // = "ButtonState"; - static const std::string xmlEventPropertyKey; // = "Key"; - static const std::string xmlEventPropertyScrollDirection; // = "ScrollDirection"; - static const std::string xmlEventPropertySignalName; // = "SignalName"; - + static const std::string xmlEventPropertyModifier(); // = "Modifiers"; + static const std::string xmlEventPropertyEventButton(); // = "EventButton"; + static const std::string xmlEventPropertyButtonState(); // = "ButtonState"; + static const std::string xmlEventPropertyKey(); // = "Key"; + static const std::string xmlEventPropertyScrollDirection(); // = "ScrollDirection"; + static const std::string xmlEventPropertySignalName(); // = "SignalName"; }; } //namespace mitk #endif //ifndef MITKINTERACTEVENTCONST_H diff --git a/Core/Code/Interactions/mitkStateMachineTransition.cpp b/Core/Code/Interactions/mitkStateMachineTransition.cpp index d5b629df0e..020d23e7ad 100755 --- a/Core/Code/Interactions/mitkStateMachineTransition.cpp +++ b/Core/Code/Interactions/mitkStateMachineTransition.cpp @@ -1,99 +1,99 @@ /*=================================================================== 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 "mitkStateMachineTransition.h" #include "mitkStateMachineAction.h" #include "mitkStateMachineState.h" #include "mitkEventFactory.h" #include "mitkInteractionEventConst.h" mitk::StateMachineTransition::StateMachineTransition(const std::string& nextStateName, const std::string& eventClass, const std::string& eventVariant) : m_EventClass(eventClass) , m_EventVariant(eventVariant) , m_NextStateName(nextStateName) { PropertyList::Pointer propertyList = PropertyList::New(); - propertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass.c_str(), eventClass.c_str()); + propertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), eventClass.c_str()); m_TransitionEvent = EventFactory::CreateEvent(propertyList); } bool mitk::StateMachineTransition::operator ==(const StateMachineTransition& transition) const { // Create event based on incoming event type, // then try to cast it to the type of event that this transition holds, // if this is possible, the variant is checked // check for NULL since a corrupted state machine might cause an empty event if (m_TransitionEvent.IsNull()) { return false; } PropertyList::Pointer propertyList = PropertyList::New(); - propertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass.c_str(), transition.m_EventClass.c_str()); + propertyList->SetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), transition.m_EventClass.c_str()); InteractionEvent::Pointer tmpEvent = EventFactory::CreateEvent(propertyList); if (tmpEvent.IsNull()) { return false; } if (m_TransitionEvent->IsSuperClassOf(tmpEvent.GetPointer())) { return (this->m_EventVariant == transition.m_EventVariant); } else { // if event variants match, but super class condition is violated // this means that the configuration file, implements a class that does not // support the type in the state machine. if (this->m_EventVariant == transition.m_EventVariant) { MITK_WARN<< "Event type in Statemachine " << m_EventClass << " is not compatible to configuration class " << transition.m_EventClass; } return false; } } mitk::StateMachineTransition::~StateMachineTransition() { //needed for correct reference counting of mitkState//, for real??? m_NextState = NULL; m_Actions.clear(); } void mitk::StateMachineTransition::AddAction(const StateMachineAction::Pointer& action) { m_Actions.push_back(action); } mitk::StateMachineState::Pointer mitk::StateMachineTransition::GetNextState() const { return m_NextState; } std::string mitk::StateMachineTransition::GetNextStateName() const { return m_NextStateName; } std::vector mitk::StateMachineTransition::GetActions() const { return m_Actions; } void mitk::StateMachineTransition::SetNextState(const SpStateMachineState& nextState) { m_NextState = nextState; } diff --git a/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp b/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp index ff311ae2a6..62e8bc14e1 100644 --- a/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp +++ b/Core/Code/Rendering/mitkPointSetVtkMapper2D.cpp @@ -1,760 +1,751 @@ /*=================================================================== 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 "mitkPointSetVtkMapper2D.h" #include "mitkDataNode.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkEnumerationProperty.h" #include "mitkVtkPropRenderer.h" #include "mitkPointSet.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include - +// constructor LocalStorage mitk::PointSetVtkMapper2D::LocalStorage::LocalStorage() { // points m_UnselectedPoints = vtkSmartPointer::New(); m_SelectedPoints = vtkSmartPointer::New(); m_ContourPoints = vtkSmartPointer::New(); // scales m_UnselectedScales = vtkSmartPointer::New(); m_SelectedScales = vtkSmartPointer::New(); // distances m_DistancesBetweenPoints = vtkSmartPointer::New(); // lines m_ContourLines = vtkSmartPointer::New(); // glyph source (provides the different shapes) m_UnselectedGlyphSource2D = vtkSmartPointer::New(); m_SelectedGlyphSource2D = vtkSmartPointer::New(); // glyphs m_UnselectedGlyph3D = vtkSmartPointer::New(); m_SelectedGlyph3D = vtkSmartPointer::New(); // polydata m_VtkUnselectedPointListPolyData = vtkSmartPointer::New(); m_VtkSelectedPointListPolyData = vtkSmartPointer ::New(); m_VtkContourPolyData = vtkSmartPointer::New(); // actors m_UnselectedActor = vtkSmartPointer ::New(); m_SelectedActor = vtkSmartPointer ::New(); m_ContourActor = vtkSmartPointer ::New(); // mappers m_VtkUnselectedPolyDataMapper = vtkSmartPointer::New(); m_VtkSelectedPolyDataMapper = vtkSmartPointer::New(); m_VtkContourPolyDataMapper = vtkSmartPointer::New(); // propassembly m_PropAssembly = vtkSmartPointer ::New(); } - +// destructor LocalStorage mitk::PointSetVtkMapper2D::LocalStorage::~LocalStorage() { } // input for this mapper ( = point set) const mitk::PointSet* mitk::PointSetVtkMapper2D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } -// constructor +// constructor PointSetVtkMapper2D mitk::PointSetVtkMapper2D::PointSetVtkMapper2D() : m_Polygon(false), m_PolygonClosed(false), m_ShowPoints(true), m_ShowDistances(false), m_DistancesDecimalDigits(1), m_ShowAngles(false), m_ShowDistantLines(false), m_LineWidth(1), m_PointLineWidth(1), m_Point2DSize(6), -m_IdGlyph(3), // default: cross +m_IdGlyph(mitk::PointSetShapeProperty::CROSS), m_FillGlyphs(false) { } // destructor mitk::PointSetVtkMapper2D::~PointSetVtkMapper2D() { } // toggles visiblity of the prop assembly void mitk::PointSetVtkMapper2D::ResetMapper( BaseRenderer* renderer ) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); ls->m_PropAssembly->VisibilityOff(); } // returns propassembly vtkProp* mitk::PointSetVtkMapper2D::GetVtkProp(mitk::BaseRenderer * renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); return ls->m_PropAssembly; } static bool makePerpendicularVector2D(const mitk::Vector2D& in, mitk::Vector2D& out) { if((fabs(in[0])>0) && ( (fabs(in[0])>fabs(in[1])) || (in[1] == 0) ) ) { out[0]=-in[1]/in[0]; out[1]=1; out.Normalize(); return true; } else if(fabs(in[1])>0) { out[0]=1; out[1]=-in[0]/in[1]; out.Normalize(); return true; } else return false; } void mitk::PointSetVtkMapper2D::CreateVTKRenderObjects(mitk::BaseRenderer* renderer) { LocalStorage *ls = m_LSH.GetLocalStorage(renderer); if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_UnselectedActor)) ls->m_PropAssembly->RemovePart(ls->m_UnselectedActor); if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_SelectedActor)) ls->m_PropAssembly->RemovePart(ls->m_SelectedActor); if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_ContourActor)) ls->m_PropAssembly->RemovePart(ls->m_ContourActor); if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextActor)) ls->m_PropAssembly->RemovePart(ls->m_VtkTextActor); unsigned i = 0; for(i=0; i< ls->m_VtkTextLabelActors.size(); i++) { if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextLabelActors.at(i))) ls->m_PropAssembly->RemovePart(ls->m_VtkTextLabelActors.at(i)); } for(i=0; i< ls->m_VtkTextDistanceActors.size(); i++) { if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextDistanceActors.at(i))) ls->m_PropAssembly->RemovePart(ls->m_VtkTextDistanceActors.at(i)); } for(i=0; i< ls->m_VtkTextAngleActors.size(); i++) { if(ls->m_PropAssembly->GetParts()->IsItemPresent(ls->m_VtkTextAngleActors.at(i))) ls->m_PropAssembly->RemovePart(ls->m_VtkTextAngleActors.at(i)); } // polydata ls->m_VtkUnselectedPointListPolyData = vtkSmartPointer::New(); ls->m_VtkSelectedPointListPolyData = vtkSmartPointer ::New(); ls->m_VtkContourPolyData = vtkSmartPointer::New(); // exceptional displaying for PositionTracker -> MouseOrientationTool int mapperID; bool isInputDevice=false; if( this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice) && isInputDevice ) { if( this->GetDataNode()->GetIntProperty("BaseRendererMapperID",mapperID) && mapperID == 2) return; //The event for the PositionTracker came from the 3d widget and not needs to be displayed } // get input point set and update the PointSet mitk::PointSet::Pointer input = const_cast(this->GetInput()); /* only update the input data, if the property tells us to */ bool update = true; this->GetDataNode()->GetBoolProperty("updateDataOnRender", update); if (update == true) input->Update(); //TODO: insert last changes on timestamps int timestep = this->GetTimestep(); mitk::PointSet::DataType::Pointer itkPointSet = input->GetPointSet( timestep ); if ( itkPointSet.GetPointer() == NULL) { ls->m_PropAssembly->VisibilityOff(); return; } //iterator for point set mitk::PointSet::PointsContainer::Iterator pointsIter = itkPointSet->GetPoints()->Begin(); - mitk::PointSet::PointsContainer::Iterator pointsIterPredecessor = itkPointSet->GetPoints()->Begin(); - // PointDataContainer has additional information to each point, e.g. whether // it is selected or not mitk::PointSet::PointDataContainer::Iterator pointDataIter; pointDataIter = itkPointSet->GetPointData()->Begin(); - //check if the list for the PointDataContainer is the same size as the PointsContainer. //If not, then the points were inserted manually and can not be visualized according to the PointData (selected/unselected) bool pointDataBroken = (itkPointSet->GetPointData()->Size() != itkPointSet->GetPoints()->Size()); if(itkPointSet->GetPointData()->size() == 0 || pointDataBroken) { return; } // empty point sets, cellarrays, scalars ls->m_UnselectedPoints->Reset(); ls->m_SelectedPoints->Reset(); ls->m_ContourPoints->Reset(); ls->m_ContourLines->Reset(); ls->m_UnselectedScales->Reset(); ls->m_SelectedScales->Reset(); ls->m_DistancesBetweenPoints->Reset(); ls->m_VtkTextLabelActors.clear(); ls->m_VtkTextDistanceActors.clear(); ls->m_VtkTextAngleActors.clear(); ls->m_UnselectedScales->SetNumberOfComponents(3); ls->m_SelectedScales->SetNumberOfComponents(3); int NumberContourPoints = 0; bool pointsOnSameSideOfPlane = false; const int text2dDistance = 10; // initialize points with a random start value // current point in point set itk::Point point = pointsIter->Value(); mitk::Point3D p = point; // currently visited point mitk::Point3D lastP = point; // last visited point mitk::Vector3D vec; // p - lastP mitk::Vector3D lastVec; // lastP - point before lastP vec.Fill(0); lastVec.Fill(0); mitk::Point3D projected_p = point; // p projected on viewplane mitk::Point2D pt2d; pt2d[0] = point[0]; // projected_p in display coordinates pt2d[1] = point[1]; mitk::Point2D lastPt2d = pt2d; // last projected_p in display coordinates mitk::Point2D preLastPt2d = pt2d ; // projected_p in display coordinates before lastPt2 // get display geometry mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry(); // get plane geometry mitk::PlaneGeometry::ConstPointer planeGeometry = renderer->GetSliceNavigationController()->GetCurrentPlaneGeometry(); int count = 0; for (pointsIter=itkPointSet->GetPoints()->Begin(); pointsIter!=itkPointSet->GetPoints()->End(); pointsIter++) { lastP = p; // valid for number of points count > 0 preLastPt2d = lastPt2d; // valid only for count > 1 lastPt2d = pt2d; // valid for number of points count > 0 lastVec = vec; // valid only for counter > 1 // get current point in point set point = pointsIter->Value(); p[0] = point[0]; p[1] = point[1]; p[2] = point[2]; displayGeometry->Project(p, projected_p); displayGeometry->Map(projected_p, pt2d); displayGeometry->WorldToDisplay(pt2d, pt2d); vec = p-lastP; // valid only for counter > 0 // compute distance to current plane float diff = planeGeometry->DistanceFromPlane(point); diff = diff * diff; //MouseOrientation bool isInputDevice=false; this->GetDataNode()->GetBoolProperty("inputdevice",isInputDevice); // if point is close to current plane ( distance < 4) it will be displayed if(!isInputDevice && (diff < 4.0)) { // is point selected or not? if (pointDataIter->Value().selected) { ls->m_SelectedPoints->InsertNextPoint(point[0],point[1],point[2]); // point is scaled according to its distance to the plane ls->m_SelectedScales->InsertNextTuple3(m_Point2DSize - (2*diff),0,0); } else { ls->m_UnselectedPoints->InsertNextPoint(point[0],point[1],point[2]); // point is scaled according to its distance to the plane ls->m_UnselectedScales->InsertNextTuple3(m_Point2DSize - (2*diff),0,0); } //---- LABEL -----// // paint label for each point if available if (dynamic_cast(this->GetDataNode()->GetProperty("label")) != NULL) { const char * pointLabel = dynamic_cast( this->GetDataNode()->GetProperty("label"))->GetValue(); std::string l = pointLabel; if (input->GetSize()>1) { std::stringstream ss; ss << pointsIter->Index(); l.append(ss.str()); } ls->m_VtkTextActor = vtkSmartPointer::New(); ls->m_VtkTextActor->SetPosition(pt2d[0] + text2dDistance, pt2d[1] + text2dDistance); ls->m_VtkTextActor->SetInput(l.c_str()); ls->m_VtkTextActor->GetTextProperty()->SetOpacity( 100 ); float unselectedColor[4]; //check if there is a color property GetDataNode()->GetColor(unselectedColor); if (unselectedColor != NULL) ls->m_VtkTextActor->GetTextProperty()->SetColor(unselectedColor[0], unselectedColor[1], unselectedColor[2]); else ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0f, 1.0f, 0.0f); ls->m_VtkTextLabelActors.push_back(ls->m_VtkTextActor); } } // draw contour, distance text and angle text in render window // lines between points, which intersect the current plane, are drawn if( m_Polygon && count > 0 ) { ScalarType distance = displayGeometry->GetWorldGeometry()->SignedDistance(point); ScalarType lastDistance = displayGeometry->GetWorldGeometry()->SignedDistance(lastP); pointsOnSameSideOfPlane = (distance * lastDistance) > 0.5; // Points must be on different side of plane in order to draw a contour. // If "show distant lines" is enabled this condition is disregarded. if ( !pointsOnSameSideOfPlane || m_ShowDistantLines) { vtkSmartPointer line = vtkSmartPointer::New(); ls->m_ContourPoints->InsertNextPoint(lastP[0],lastP[1],lastP[2]); line->GetPointIds()->SetId(0, NumberContourPoints); NumberContourPoints++; ls->m_ContourPoints->InsertNextPoint(point[0], point[1], point[2]); line->GetPointIds()->SetId(1, NumberContourPoints); NumberContourPoints++; ls->m_ContourLines->InsertNextCell(line); if(m_ShowDistances) // calculate and print distance between adjacent points { float distancePoints = point.EuclideanDistanceTo(lastP); std::stringstream buffer; buffer<m_VtkTextActor = vtkSmartPointer::New(); ls->m_VtkTextActor->SetPosition(pos2d[0],pos2d[1]); ls->m_VtkTextActor->SetInput(buffer.str().c_str()); ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0); ls->m_VtkTextDistanceActors.push_back(ls->m_VtkTextActor); } if(m_ShowAngles && count > 1) // calculate and print angle between connected lines { std::stringstream buffer; //(char) 176 is the degree sign buffer << angle(vec.GetVnlVector(), -lastVec.GetVnlVector())*180/vnl_math::pi << (char)176; //compute desired display position of text Vector2D vec2d = pt2d-lastPt2d; // first arm enclosing the angle vec2d.Normalize(); Vector2D lastVec2d = lastPt2d-preLastPt2d; // second arm enclosing the angle lastVec2d.Normalize(); vec2d=vec2d-lastVec2d; // vector connecting both arms vec2d.Normalize(); // middle between two vectors that enclose the angle Vector2D pos2d = lastPt2d.GetVectorFromOrigin() + vec2d * text2dDistance * text2dDistance; ls->m_VtkTextActor = vtkSmartPointer::New(); ls->m_VtkTextActor->SetPosition(pos2d[0],pos2d[1]); ls->m_VtkTextActor->SetInput(buffer.str().c_str()); ls->m_VtkTextActor->GetTextProperty()->SetColor(0.0, 1.0, 0.0); ls->m_VtkTextAngleActors.push_back(ls->m_VtkTextActor); } } } if(pointDataIter != itkPointSet->GetPointData()->End()) { pointDataIter++; count++; } } // add each single text actor to the assembly for(i=0; i< ls->m_VtkTextLabelActors.size(); i++) { ls->m_PropAssembly->AddPart(ls->m_VtkTextLabelActors.at(i)); } for(i=0; i< ls->m_VtkTextDistanceActors.size(); i++) { ls->m_PropAssembly->AddPart(ls->m_VtkTextDistanceActors.at(i)); } for(i=0; i< ls->m_VtkTextAngleActors.size(); i++) { ls->m_PropAssembly->AddPart(ls->m_VtkTextAngleActors.at(i)); } //---- CONTOUR -----// //create lines between the points which intersect the plane if (m_Polygon) { // draw line between first and last point which is rendered if(m_PolygonClosed && NumberContourPoints > 1){ vtkSmartPointer closingLine = vtkSmartPointer::New(); closingLine->GetPointIds()->SetId(0, 0); // index of first point closingLine->GetPointIds()->SetId(1, NumberContourPoints-1); // index of last point ls->m_ContourLines->InsertNextCell(closingLine); } ls->m_VtkContourPolyData->SetPoints(ls->m_ContourPoints); ls->m_VtkContourPolyData->SetLines(ls->m_ContourLines); ls->m_VtkContourPolyDataMapper->SetInput(ls->m_VtkContourPolyData); ls->m_ContourActor->SetMapper(ls->m_VtkContourPolyDataMapper); ls->m_ContourActor->GetProperty()->SetLineWidth(m_LineWidth); ls->m_PropAssembly->AddPart(ls->m_ContourActor); } // the point set must be transformed in order to obtain the appropriate glyph orientation // according to the current view vtkSmartPointer transform = vtkSmartPointer::New(); vtkSmartPointer a,b = vtkSmartPointer::New(); a = planeGeometry->GetVtkTransform()->GetMatrix(); b->DeepCopy( a ); // delete transformation from matrix, only take orientation b->SetElement(3,3,1); b->SetElement(2,3,0); b->SetElement(1,3,0); b->SetElement(0,3,0); b->SetElement(3,2,0); b->SetElement(3,1,0); b->SetElement(3,0,0); transform->SetMatrix( b ); //---- UNSELECTED POINTS -----// // apply properties to glyph ls->m_UnselectedGlyphSource2D->SetGlyphType(m_IdGlyph); if(m_FillGlyphs) ls->m_UnselectedGlyphSource2D->FilledOn(); else ls->m_UnselectedGlyphSource2D->FilledOff(); // apply transform vtkSmartPointer transformFilterU = vtkSmartPointer::New(); transformFilterU->SetInputConnection(ls->m_UnselectedGlyphSource2D->GetOutputPort()); transformFilterU->SetTransform(transform); ls->m_VtkUnselectedPointListPolyData->SetPoints(ls->m_UnselectedPoints); ls->m_VtkUnselectedPointListPolyData->GetPointData()->SetVectors(ls->m_UnselectedScales); // apply transform of current plane to glyphs ls->m_UnselectedGlyph3D->SetSourceConnection(transformFilterU->GetOutputPort()); ls->m_UnselectedGlyph3D->SetInput(ls->m_VtkUnselectedPointListPolyData); ls->m_UnselectedGlyph3D->SetScaleModeToScaleByVector(); ls->m_UnselectedGlyph3D->SetVectorModeToUseVector(); ls->m_VtkUnselectedPolyDataMapper->SetInput(ls->m_UnselectedGlyph3D->GetOutput()); ls->m_UnselectedActor->SetMapper(ls->m_VtkUnselectedPolyDataMapper); ls->m_UnselectedActor->GetProperty()->SetLineWidth(m_PointLineWidth); ls->m_PropAssembly->AddPart(ls->m_UnselectedActor); //---- SELECTED POINTS -----// ls->m_SelectedGlyphSource2D->SetGlyphTypeToDiamond(); ls->m_SelectedGlyphSource2D->CrossOn(); ls->m_SelectedGlyphSource2D->FilledOff(); // apply transform vtkSmartPointer transformFilterS = vtkSmartPointer::New(); transformFilterS->SetInputConnection(ls->m_SelectedGlyphSource2D->GetOutputPort()); transformFilterS->SetTransform(transform); ls->m_VtkSelectedPointListPolyData->SetPoints(ls->m_SelectedPoints); ls->m_VtkSelectedPointListPolyData->GetPointData()->SetVectors(ls->m_SelectedScales); // apply transform of current plane to glyphs ls->m_SelectedGlyph3D->SetSourceConnection(transformFilterS->GetOutputPort()); ls->m_SelectedGlyph3D->SetInput(ls->m_VtkSelectedPointListPolyData); ls->m_SelectedGlyph3D->SetScaleModeToScaleByVector(); ls->m_SelectedGlyph3D->SetVectorModeToUseVector(); ls->m_VtkSelectedPolyDataMapper->SetInput(ls->m_SelectedGlyph3D->GetOutput()); ls->m_SelectedActor->SetMapper(ls->m_VtkSelectedPolyDataMapper); ls->m_SelectedActor->GetProperty()->SetLineWidth(m_PointLineWidth); ls->m_PropAssembly->AddPart(ls->m_SelectedActor); } void mitk::PointSetVtkMapper2D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { const mitk::DataNode* node = GetDataNode(); if( node == NULL ) return; LocalStorage *ls = m_LSH.GetLocalStorage(renderer); bool needGenerateData = ls->IsGenerateDataRequired( renderer, this, GetDataNode() ); // toggle visibility bool visible = true; node->GetVisibility(visible, renderer, "visible"); if(!visible) { ls->m_UnselectedActor->VisibilityOff(); ls->m_SelectedActor->VisibilityOff(); ls->m_ContourActor->VisibilityOff(); ls->m_PropAssembly->VisibilityOff(); return; }else{ ls->m_PropAssembly->VisibilityOn(); } node->GetBoolProperty("show contour", m_Polygon, renderer); node->GetBoolProperty("close contour", m_PolygonClosed, renderer); node->GetBoolProperty("show points", m_ShowPoints, renderer); node->GetBoolProperty("show distances", m_ShowDistances, renderer); node->GetIntProperty("distance decimal digits", m_DistancesDecimalDigits, renderer); node->GetBoolProperty("show angles", m_ShowAngles, renderer); node->GetBoolProperty("show distant lines", m_ShowDistantLines, renderer); node->GetIntProperty("line width", m_LineWidth, renderer); node->GetIntProperty("point line width", m_PointLineWidth, renderer); node->GetIntProperty("point 2D size", m_Point2DSize, renderer); node->GetBoolProperty("Pointset.2D.fill shape", m_FillGlyphs, renderer); - mitk::PointSetShapeProperty::Pointer shape = dynamic_cast(this->GetDataNode()->GetProperty( "Pointset.2D.shape", renderer )); if(shape.IsNotNull()) { m_IdGlyph = shape->GetPointSetShape(); } - //check for color props and use it for rendering of selected/unselected points and contour //due to different params in VTK (double/float) we have to convert float unselectedColor[4]; vtkFloatingPointType selectedColor[4]={1.0f,0.0f,0.0f,1.0f}; //red vtkFloatingPointType contourColor[4]={1.0f,0.0f,0.0f,1.0f}; //red float opacity = 1.0; GetDataNode()->GetOpacity(opacity, renderer); // apply color and opacity if(m_ShowPoints) { ls->m_UnselectedActor->VisibilityOn(); ls->m_SelectedActor->VisibilityOn(); //check if there is a color property GetDataNode()->GetColor(unselectedColor); //get selected color property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; // alpha value } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("selectedcolor"))->GetValue(); selectedColor[0] = tmpColor[0]; selectedColor[1] = tmpColor[1]; selectedColor[2] = tmpColor[2]; selectedColor[3] = 1.0f; // alpha value } ls->m_SelectedActor->GetProperty()->SetColor(selectedColor); ls->m_SelectedActor->GetProperty()->SetOpacity(opacity); ls->m_UnselectedActor->GetProperty()->SetColor(unselectedColor[0],unselectedColor[1],unselectedColor[2]); ls->m_UnselectedActor->GetProperty()->SetOpacity(opacity); } else { ls->m_UnselectedActor->VisibilityOff(); ls-> m_SelectedActor->VisibilityOff(); } - if (m_Polygon) { ls->m_ContourActor->VisibilityOn(); //get contour color property if (dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(renderer)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } else if (dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor")) != NULL) { mitk::Color tmpColor = dynamic_cast(this->GetDataNode()->GetPropertyList(NULL)->GetProperty("contourcolor"))->GetValue(); contourColor[0] = tmpColor[0]; contourColor[1] = tmpColor[1]; contourColor[2] = tmpColor[2]; contourColor[3] = 1.0f; } ls->m_ContourActor->GetProperty()->SetColor(contourColor); ls->m_ContourActor->GetProperty()->SetOpacity(opacity); } else { ls->m_ContourActor->VisibilityOff(); } if(needGenerateData) { // create new vtk render objects (e.g. a circle for a point) this->CreateVTKRenderObjects(renderer); } - } - - void mitk::PointSetVtkMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); node->AddProperty( "point 2D size", mitk::IntProperty::New(6), renderer, overwrite ); node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "close contour", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); node->AddProperty( "layer", mitk::IntProperty::New(1), renderer, overwrite ); node->AddProperty( "Pointset.2D.fill shape", mitk::BoolProperty::New(false), renderer, overwrite); // fill or do not fill the glyph shape mitk::PointSetShapeProperty::Pointer pointsetShapeProperty = mitk::PointSetShapeProperty::New(); node->AddProperty( "Pointset.2D.shape", pointsetShapeProperty, renderer, overwrite); Superclass::SetDefaultProperties(node, renderer, overwrite); } diff --git a/Core/Code/Testing/mitkEventConfigTest.cpp b/Core/Code/Testing/mitkEventConfigTest.cpp index 2419f5ae7f..f3db0b9efd 100644 --- a/Core/Code/Testing/mitkEventConfigTest.cpp +++ b/Core/Code/Testing/mitkEventConfigTest.cpp @@ -1,151 +1,151 @@ /*=================================================================== 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 "mitkEventConfig.h" #include "mitkPropertyList.h" #include "mitkInteractionEvent.h" #include "mitkInteractionEventConst.h" #include "mitkMouseMoveEvent.h" #include "mitkMouseWheelEvent.h" #include "mitkMouseReleaseEvent.h" #include "mitkInteractionKeyEvent.h" #include "mitkMousePressEvent.h" #include "mitkModule.h" #include "mitkGetModuleContext.h" #include #include #include int mitkEventConfigTest(int argc, char* argv[]) { MITK_TEST_BEGIN("EventConfig") if (argc != 2) { MITK_ERROR << "Test needs configuration test file as parameter."; return -1; } /* * Loads a test a Config file and test if Config is build up correctly, * and if mapping from mitkEvents to EventVariant names works properly. * Indirectly this also tests the EventFactory Class, since we also test if the events have been constructed properly. * * The configuration object is constructed in three different ways, * each one is tested here. */ // Construction using compiled-in resrouces: mitk::Module *module = mitk::GetModuleContext()->GetModule(); mitk::EventConfig newConfig("StatemachineConfigTest.xml",module); MITK_TEST_CONDITION_REQUIRED( newConfig.IsValid() == true , "01 Check if file can be loaded and is valid" ); /* * Test the global properties: * Test if stored values match the ones in the test config file. */ mitk::PropertyList::Pointer properties = newConfig.GetAttributes(); std::string prop1, prop2; MITK_TEST_CONDITION_REQUIRED( properties->GetStringProperty("property1",prop1) && prop1 == "yes" && properties->GetStringProperty("scrollModus",prop2) && prop2 == "leftright" , "02 Check Global Properties"); /* * Check if Events get mapped to the proper Variants */ mitk::Point2D pos; mitk::MousePressEvent::Pointer mpe1 = mitk::MousePressEvent::New(NULL,pos,mitk::InteractionEvent::MiddleMouseButton | mitk::InteractionEvent::LeftMouseButton ,mitk::InteractionEvent::ControlKey | mitk::InteractionEvent::AltKey,mitk::InteractionEvent::LeftMouseButton ); mitk::MousePressEvent::Pointer standard1 = mitk::MousePressEvent::New(NULL,pos,mitk::InteractionEvent::LeftMouseButton,mitk::InteractionEvent::NoKey ,mitk::InteractionEvent::LeftMouseButton ); mitk::MouseMoveEvent::Pointer mme1 = mitk::MouseMoveEvent::New(NULL,pos,mitk::InteractionEvent::RightMouseButton | mitk::InteractionEvent::LeftMouseButton,mitk::InteractionEvent::ShiftKey ); mitk::MouseMoveEvent::Pointer mme2 = mitk::MouseMoveEvent::New(NULL,pos,mitk::InteractionEvent::RightMouseButton,mitk::InteractionEvent::ShiftKey ); mitk::MouseWheelEvent::Pointer mwe1 = mitk::MouseWheelEvent::New(NULL,pos,mitk::InteractionEvent::RightMouseButton,mitk::InteractionEvent::ShiftKey,-2 ); mitk::InteractionKeyEvent::Pointer ke = mitk::InteractionKeyEvent::New(NULL,"l",mitk::InteractionEvent::NoKey ); MITK_TEST_CONDITION_REQUIRED( newConfig.GetMappedEvent(mpe1.GetPointer()) == "Variant1" && newConfig.GetMappedEvent(standard1.GetPointer()) == "Standard1" && newConfig.GetMappedEvent(mme1.GetPointer()) == "Move2" && newConfig.GetMappedEvent(ke.GetPointer()) == "Key1" && newConfig.GetMappedEvent(mme2.GetPointer()) == "" // does not exist in file , "03 Check Mouse- and Key-Events " ); // Construction providing a input stream std::ifstream configStream(argv[1]); mitk::EventConfig newConfig2(configStream); MITK_TEST_CONDITION_REQUIRED( newConfig2.IsValid() == true , "01 Check if file can be loaded and is valid" ); /* * Test the global properties: * Test if stored values match the ones in the test config file. */ properties = newConfig2.GetAttributes(); MITK_TEST_CONDITION_REQUIRED( properties->GetStringProperty("property1",prop1) && prop1 == "yes" && properties->GetStringProperty("scrollModus",prop2) && prop2 == "leftright" , "02 Check Global Properties"); /* * Check if Events get mapped to the proper Variants */ MITK_TEST_CONDITION_REQUIRED( newConfig2.GetMappedEvent(mpe1.GetPointer()) == "Variant1" && newConfig2.GetMappedEvent(standard1.GetPointer()) == "Standard1" && newConfig2.GetMappedEvent(mme1.GetPointer()) == "Move2" && newConfig2.GetMappedEvent(ke.GetPointer()) == "Key1" && newConfig2.GetMappedEvent(mme2.GetPointer()) == "" // does not exist in file , "03 Check Mouse- and Key-Events " ); // always end with this! // Construction providing a property list mitk::PropertyList::Pointer propertyList1 = mitk::PropertyList::New(); - propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass.c_str(), "MousePressEvent"); - propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant.c_str(), "MousePressEventVariant"); + propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass().c_str(), "MousePressEvent"); + propertyList1->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant().c_str(), "MousePressEventVariant"); propertyList1->SetStringProperty("Modifiers","CTRL,ALT"); mitk::PropertyList::Pointer propertyList2 = mitk::PropertyList::New(); - propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass.c_str(), "MOUSERELEASEEVENT"); - propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant.c_str(), "MouseReleaseEventVariant"); + propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventClass().c_str(), "MOUSERELEASEEVENT"); + propertyList2->SetStringProperty(mitk::InteractionEventConst::xmlParameterEventVariant().c_str(), "MouseReleaseEventVariant"); propertyList2->SetStringProperty("Modifiers","SHIFT"); std::vector* configDescription = new std::vector(); configDescription->push_back(propertyList1); configDescription->push_back(propertyList2); mitk::EventConfig newConfig3(*configDescription); mitk::MousePressEvent::Pointer mousePress1 = mitk::MousePressEvent::New(NULL,pos,mitk::InteractionEvent::NoButton,mitk::InteractionEvent::AltKey | mitk::InteractionEvent::ControlKey ,mitk::InteractionEvent::NoButton ); mitk::MouseReleaseEvent::Pointer mousePress2 = mitk::MouseReleaseEvent::New(NULL,pos,mitk::InteractionEvent::NoButton,mitk::InteractionEvent::ShiftKey ,mitk::InteractionEvent::NoButton ); MITK_TEST_CONDITION_REQUIRED( newConfig3.GetMappedEvent(mousePress1.GetPointer()) == "MousePressEventVariant" && newConfig3.GetMappedEvent(mousePress2.GetPointer()) == "MouseReleaseEventVariant" , "04 Check Mouseevents from PropertyLists" ); MITK_TEST_END() } diff --git a/Core/Code/Testing/mitkImageTest.cpp b/Core/Code/Testing/mitkImageTest.cpp index e215edf90f..aff7a8715b 100644 --- a/Core/Code/Testing/mitkImageTest.cpp +++ b/Core/Code/Testing/mitkImageTest.cpp @@ -1,381 +1,432 @@ /*=================================================================== 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 includes #include #include #include #include "mitkItkImageFileReader.h" #include #include +#include "mitkImageGenerator.h" // itk includes #include #include // stl includes #include // vtk includes #include // Checks if reference count is correct after using GetVtkImageData() bool ImageVtkDataReferenceCheck(const char* fname) { const std::string filename = std::string(fname); mitk::ItkImageFileReader::Pointer imageReader = mitk::ItkImageFileReader::New(); try { imageReader->SetFileName(filename); imageReader->Update(); } catch(...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return false; } { mitk::Image::Pointer image = imageReader->GetOutput(); vtkImageData* vtk = image->GetVtkImageData(); if(vtk == NULL) return false; } return true; } +class mitkImageTestClass +{ +public: + void SetClonedGeometry_None_ClonedEqualInput() + { + mitk::Image::Pointer image = mitk::ImageGenerator::GenerateRandomImage(100, 100, 100, 1, 0.2, 0.3, 0.4); + + //----------------- + // geometry information for image + mitk::Point3D origin; + mitk::Vector3D right, bottom; + mitk::Vector3D spacing; + mitk::FillVector3D(origin, 17.0, 19.92, 7.83); + mitk::FillVector3D(right, 1.0, 2.0, 3.0); + mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); + mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); + + //InitializeStandardPlane(rightVector, downVector, spacing) + mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); + planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); + planegeometry->SetOrigin(origin); + planegeometry->ChangeImageGeometryConsideringOriginOffset(true); + + image->SetClonedGeometry(planegeometry); + + mitk::Geometry3D::Pointer imageGeometry = image->GetGeometry(); + itk::ScalableAffineTransform* frameNew = imageGeometry->GetIndexToWorldTransform(); + itk::ScalableAffineTransform* frameOld = planegeometry->GetIndexToWorldTransform(); + bool matrixEqual = true; + for (int i = 0; i < 16; ++i) + { + double valueNew = *(frameNew->GetMatrix()[i]); + double valueOld = *(frameOld->GetMatrix()[i]); + + //MITK_INFO << "Index: " << i << " Old: " << valueOld << " New: " << valueNew << " Difference:" << valueOld-valueNew<< std::endl; + matrixEqual = matrixEqual && mitk::Equal(valueNew, valueOld, mitk::eps); + } + + // Disabled because this test fails on the dashboard. Does not fail on my machine. + // See Bug 6505 + // MITK_TEST_CONDITION(matrixEqual, "Matrix elements of cloned matrix equal original matrix"); + + } +}; + + int mitkImageTest(int argc, char* argv[]) { MITK_TEST_BEGIN(mitkImageTest); + mitkImageTestClass tester; + tester.SetClonedGeometry_None_ClonedEqualInput(); + + //Create Image out of nowhere mitk::Image::Pointer imgMem = mitk::Image::New(); mitk::PixelType pt = mitk::MakeScalarPixelType(); unsigned int dim[]={100,100,20}; MITK_TEST_CONDITION_REQUIRED( imgMem.IsNotNull(), "An image was created. "); // Initialize image imgMem->Initialize( pt, 3, dim); MITK_TEST_CONDITION_REQUIRED( imgMem->IsInitialized(), "Image::IsInitialized() ?"); MITK_TEST_CONDITION_REQUIRED( imgMem->GetPixelType() == pt, "PixelType was set correctly."); int *p = (int*)imgMem->GetData(); MITK_TEST_CONDITION( p != NULL, "GetData() returned not-NULL pointer."); // FIXME: this is directly changing the image data // filling image const unsigned int size = dim[0]*dim[1]*dim[2]; for(unsigned int i=0; iGetData(); MITK_TEST_CONDITION( p2 != NULL, "GetData() returned not-NULL pointer."); bool isEqual = true; for(unsigned int i=0; iGetSliceData(dim[2]/2)->GetData(); MITK_TEST_CONDITION_REQUIRED( p2 != NULL, "Valid slice data returned"); unsigned int xy_size = dim[0]*dim[1]; unsigned int start_mid_slice = (dim[2]/2)*xy_size; isEqual = true; for(unsigned int i=0; i(); imgMem->Initialize( pType , 3, dim); MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension()== 3, "Testing initialization parameter dimension!"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetPixelType() == pType, "Testing initialization parameter pixeltype!"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetDimension(0) == dim[0] && imgMem->GetDimension(1)== dim[1] && imgMem->GetDimension(2)== dim[2], "Testing initialization of dimensions!"); MITK_TEST_CONDITION( imgMem->IsInitialized(), "Image is initialized."); // Setting volume again: imgMem->SetVolume(imgMem->GetData()); //----------------- // geometry information for image mitk::Point3D origin; mitk::Vector3D right, bottom; mitk::Vector3D spacing; mitk::FillVector3D(origin, 17.0, 19.92, 7.83); mitk::FillVector3D(right, 1.0, 2.0, 3.0); mitk::FillVector3D(bottom, 0.0, -3.0, 2.0); mitk::FillVector3D(spacing, 0.78, 0.91, 2.23); //InitializeStandardPlane(rightVector, downVector, spacing) mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New(); planegeometry->InitializeStandardPlane(100, 100, right, bottom, &spacing); planegeometry->SetOrigin(origin); // Testing Initialize(const mitk::PixelType& type, const mitk::Geometry3D& geometry, unsigned int slices) with PlaneGeometry and GetData(): "; imgMem->Initialize( mitk::MakePixelType(), *planegeometry); MITK_TEST_CONDITION_REQUIRED( imgMem->GetGeometry()->GetOrigin() == static_cast(planegeometry)->GetOrigin(), "Testing correct setting of geometry via initialize!"); p = (int*)imgMem->GetData(); MITK_TEST_CONDITION_REQUIRED( p!=NULL, "GetData() returned valid pointer."); // Testing Initialize(const mitk::PixelType& type, int sDim, const mitk::PlaneGeometry& geometry) and GetData(): "; imgMem->Initialize( mitk::MakePixelType() , 40, *planegeometry); p = (int*)imgMem->GetData(); MITK_TEST_CONDITION_REQUIRED( p!=NULL, "GetData() returned valid pointer."); //----------------- // testing origin information and methods MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetGeometry()->GetOrigin(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetOrigin(), origin), "Testing correctness of origin via GetTimeSlicedGeometry()->GetOrigin(): "); // Setting origin via SetOrigin(origin): "; mitk::FillVector3D(origin, 37.0, 17.92, 27.83); imgMem->SetOrigin(origin); // Test origin MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetGeometry()->GetOrigin(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetOrigin(), origin), "Testing correctness of changed origin via GetTimeSlicedGeometry()->GetOrigin(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetGeometry2D(0)->GetOrigin(), origin), "Testing correctness of changed origin via GetSlicedGeometry()->GetGeometry2D(0)->GetOrigin(): "); //----------------- // testing spacing information and methods MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correct spacing from Geometry3D!"); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetSpacing(), spacing), "Testing correctspacing from TimeSlicedGeometry!"); mitk::FillVector3D(spacing, 7.0, 0.92, 1.83); imgMem->SetSpacing(spacing); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetGeometry()->GetSpacing(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetTimeSlicedGeometry()->GetSpacing(), spacing), "Testing correctness of changed spacing via GetTimeSlicedGeometry()->GetSpacing(): "); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(imgMem->GetSlicedGeometry()->GetGeometry2D(0)->GetSpacing(), spacing), "Testing correctness of changed spacing via GetSlicedGeometry()->GetGeometry2D(0)->GetSpacing(): "); mitk::Image::Pointer vecImg = mitk::Image::New(); vecImg->Initialize( imgMem->GetPixelType(), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/ ); vecImg->SetImportChannel(imgMem->GetData(), 0, mitk::Image::CopyMemory ); vecImg->SetImportChannel(imgMem->GetData(), 1, mitk::Image::CopyMemory ); MITK_TEST_CONDITION_REQUIRED(vecImg->GetChannelData(0)->GetData() != NULL && vecImg->GetChannelData(1)->GetData() != NULL, "Testing set and return of channel data!"); MITK_TEST_CONDITION_REQUIRED( vecImg->IsValidSlice(0,0,1) , ""); MITK_TEST_OUTPUT(<< " Testing whether CopyMemory worked"); MITK_TEST_CONDITION_REQUIRED(imgMem->GetData() != vecImg->GetData(), ""); MITK_TEST_OUTPUT(<< " Testing destruction after SetImportChannel"); vecImg = NULL; MITK_TEST_CONDITION_REQUIRED(vecImg.IsNull() , "testing destruction!"); //----------------- MITK_TEST_OUTPUT(<< "Testing initialization via vtkImageData"); MITK_TEST_OUTPUT(<< " Setting up vtkImageData"); vtkImageData* vtkimage = vtkImageData::New(); vtkimage->Initialize(); vtkimage->SetDimensions( 2, 3, 4); double vtkorigin[] = {-350,-358.203, -1363.5}; vtkimage->SetOrigin(vtkorigin); mitk::Point3D vtkoriginAsMitkPoint; mitk::vtk2itk(vtkorigin, vtkoriginAsMitkPoint); double vtkspacing[] = {1.367, 1.367, 2}; vtkimage->SetSpacing(vtkspacing); vtkimage->SetScalarType( VTK_SHORT ); vtkimage->AllocateScalars(); std::cout<<"[PASSED]"<Initialize(vtkimage); MITK_TEST_CONDITION_REQUIRED(mitkByVtkImage->IsInitialized(), ""); vtkimage->Delete(); MITK_TEST_OUTPUT(<< " Testing whether spacing has been correctly initialized from vtkImageData"); mitk::Vector3D spacing2 = mitkByVtkImage->GetGeometry()->GetSpacing(); mitk::Vector3D vtkspacingAsMitkVector; mitk::vtk2itk(vtkspacing, vtkspacingAsMitkVector); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(spacing2,vtkspacingAsMitkVector), ""); MITK_TEST_OUTPUT(<< " Testing whether GetSlicedGeometry(0)->GetOrigin() has been correctly initialized from vtkImageData"); mitk::Point3D origin2 = mitkByVtkImage->GetSlicedGeometry(0)->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing whether GetGeometry()->GetOrigin() has been correctly initialized from vtkImageData"); origin2 = mitkByVtkImage->GetGeometry()->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), ""); MITK_TEST_OUTPUT(<< " Testing whether GetTimeSlicedGeometry()->GetOrigin() has been correctly initialized from vtkImageData"); origin2 = mitkByVtkImage->GetTimeSlicedGeometry()->GetOrigin(); MITK_TEST_CONDITION_REQUIRED(mitk::Equal(origin2,vtkoriginAsMitkPoint), ""); // TODO test the following initializers on channel-incorporation // void mitk::Image::Initialize(const mitk::PixelType& type, unsigned int dimension, unsigned int *dimensions, unsigned int channels) // void mitk::Image::Initialize(const mitk::PixelType& type, int sDim, const mitk::Geometry2D& geometry2d, bool flipped, unsigned int channels, int tDim ) // void mitk::Image::Initialize(const mitk::Image* image) // void mitk::Image::Initialize(const mitkIpPicDescriptor* pic, int channels, int tDim, int sDim) //mitk::Image::Pointer vecImg = mitk::Image::New(); //vecImg->Initialize(PixelType(typeid(float), 6, itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ ); //vecImg->Initialize(PixelType(typeid(itk::Vector)), *imgMem->GetGeometry(), 2 /* #channels */, 0 /*tDim*/, false /*shiftBoundingBoxMinimumToZero*/ ); // testing access by index coordinates and by world coordinates MITK_TEST_CONDITION_REQUIRED(argc == 2, "Check if test image is accessible!"); const std::string filename = std::string(argv[1]); mitk::ItkImageFileReader::Pointer imageReader = mitk::ItkImageFileReader::New(); try { imageReader->SetFileName(filename); imageReader->Update(); } catch(...) { MITK_TEST_FAILED_MSG(<< "Could not read file for testing: " << filename); return 0; } mitk::Image::Pointer image = imageReader->GetOutput(); // generate a random point in world coordinates mitk::Point3D xMax, yMax, zMax, xMaxIndex, yMaxIndex, zMaxIndex; xMaxIndex.Fill(0.0f); yMaxIndex.Fill(0.0f); zMaxIndex.Fill(0.0f); xMaxIndex[0] = image->GetLargestPossibleRegion().GetSize()[0]; yMaxIndex[1] = image->GetLargestPossibleRegion().GetSize()[1]; zMaxIndex[2] = image->GetLargestPossibleRegion().GetSize()[2]; image->GetGeometry()->IndexToWorld(xMaxIndex, xMax); image->GetGeometry()->IndexToWorld(yMaxIndex, yMax); image->GetGeometry()->IndexToWorld(zMaxIndex, zMax); MITK_INFO << "Origin " << image->GetGeometry()->GetOrigin()[0] << " "<< image->GetGeometry()->GetOrigin()[1] << " "<< image->GetGeometry()->GetOrigin()[2] << ""; MITK_INFO << "MaxExtend " << xMax[0] << " "<< yMax[1] << " "<< zMax[2] << ""; mitk::Point3D point; itk::Statistics::MersenneTwisterRandomVariateGenerator::Pointer randomGenerator = itk::Statistics::MersenneTwisterRandomVariateGenerator::New(); randomGenerator->Initialize( std::rand() ); // initialize with random value, to get sensible random points for the image point[0] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[0], xMax[0]); point[1] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[1], yMax[1]); point[2] = randomGenerator->GetUniformVariate( image->GetGeometry()->GetOrigin()[2], zMax[2]); MITK_INFO << "RandomPoint " << point[0] << " "<< point[1] << " "<< point[2] << ""; // test values and max/min mitk::ScalarType imageMin = image->GetStatistics()->GetScalarValueMin(); mitk::ScalarType imageMax = image->GetStatistics()->GetScalarValueMax(); mitk::ScalarType value = image->GetPixelValueByWorldCoordinate(point); MITK_INFO << imageMin << " "<< imageMax << " "<< value << ""; MITK_TEST_CONDITION( (value >= imageMin && value <= imageMax), "Value returned is between max/min"); // test accessing PixelValue with coordinate leading to a negative index const mitk::Point3D geom_origin = image->GetGeometry()->GetOrigin(); const mitk::Point3D geom_center = image->GetGeometry()->GetCenter(); const unsigned int timestep = 0; // shift position from origin outside of the image ( in the opposite direction to [center-origin] vector which points in the inside) mitk::Point3D position = geom_origin + (geom_origin - geom_center); MITK_TEST_CONDITION_REQUIRED( image->GetPixelValueByWorldCoordinate(position, timestep) == 0, "Test access to the outside of the image") // testing the clone method of mitk::Image mitk::Image::Pointer cloneImage = image->Clone(); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension() == image->GetDimension(), "Clone (testing dimension)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetPixelType() == image->GetPixelType(), "Clone (testing pixel type)"); // After cloning an image the geometry of both images should be equal too MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetOrigin() == image->GetGeometry()->GetOrigin(), "Clone (testing origin)"); MITK_TEST_CONDITION_REQUIRED(cloneImage->GetGeometry()->GetSpacing() == image->GetGeometry()->GetSpacing(), "Clone (testing spacing)"); MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(cloneImage->GetGeometry()->GetIndexToWorldTransform()->GetMatrix(), image->GetGeometry()->GetIndexToWorldTransform()->GetMatrix()), "Clone (testing transformation matrix)"); MITK_TEST_CONDITION_REQUIRED(mitk::MatrixEqualElementWise(cloneImage->GetTimeSlicedGeometry()->GetGeometry3D(cloneImage->GetDimension(3)-1)->GetIndexToWorldTransform()->GetMatrix(), cloneImage->GetTimeSlicedGeometry()->GetGeometry3D(image->GetDimension(3)-1)->GetIndexToWorldTransform()->GetMatrix()), "Clone(testing time sliced geometry)"); for (unsigned int i = 0u; i < cloneImage->GetDimension(); ++i) { MITK_TEST_CONDITION_REQUIRED(cloneImage->GetDimension(i) == image->GetDimension(i), "Clone (testing dimension " << i << ")"); } //access via itk if(image->GetDimension()> 3) // CastToItk only works with 3d images so we need to check for 4d images { mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New(); selector->SetTimeNr(0); selector->SetInput(image); selector->Update(); image = selector->GetOutput(); } if(image->GetDimension()==3) { typedef itk::Image ItkFloatImage3D; ItkFloatImage3D::Pointer itkimage; mitk::CastToItkImage(image, itkimage); MITK_TEST_CONDITION_REQUIRED(itkimage.IsNotNull(), "Test conversion to itk::Image!"); mitk::Point3D itkPhysicalPoint; image->GetGeometry()->WorldToItkPhysicalPoint(point, itkPhysicalPoint); MITK_INFO << "ITKPoint " << itkPhysicalPoint[0] << " "<< itkPhysicalPoint[1] << " "<< itkPhysicalPoint[2] << ""; mitk::Point3D backTransformedPoint; image->GetGeometry()->ItkPhysicalPointToWorld(itkPhysicalPoint, backTransformedPoint); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(point,backTransformedPoint), "Testing world->itk-physical->world consistency"); itk::Index<3> idx; bool status = itkimage->TransformPhysicalPointToIndex(itkPhysicalPoint, idx); MITK_INFO << "ITK Index " << idx[0] << " "<< idx[1] << " "<< idx[2] << ""; if(status) { float valByItk = itkimage->GetPixel(idx); MITK_TEST_CONDITION_REQUIRED( mitk::Equal(valByItk, value), "Compare value of pixel returned by mitk in comparison to itk"); } else { MITK_WARN<< "Index is out buffered region!"; } } else { MITK_INFO << "Image does not contain three dimensions, some test cases are skipped!"; } // clone generated 3D image with one slice in z direction (cf. bug 11058) unsigned int* threeDdim = new unsigned int[3]; threeDdim[0] = 100; threeDdim[1] = 200; threeDdim[2] = 1; mitk::Image::Pointer threeDImage = mitk::Image::New(); threeDImage->Initialize(mitk::MakeScalarPixelType(), 3, threeDdim); mitk::Image::Pointer cloneThreeDImage = threeDImage->Clone(); // check that the clone image has the same dimensionality as the source image MITK_TEST_CONDITION_REQUIRED( cloneThreeDImage->GetDimension() == 3, "Testing if the clone image initializes with 3D!"); MITK_TEST_CONDITION_REQUIRED( ImageVtkDataReferenceCheck(argv[1]), "Checking reference count of Image after using GetVtkImageData()"); MITK_TEST_END(); } diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp index d1ea4ab817..845c27ddfc 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp @@ -1,781 +1,781 @@ /*=================================================================== 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 __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_cpp #define __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_cpp #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "itkRegularizedIVIMReconstructionFilter.h" #include #define IVIM_FOO -100000 namespace itk { template< class TIn, class TOut> DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::DiffusionIntravoxelIncoherentMotionReconstructionImageFilter() : m_GradientDirectionContainer(NULL), m_Method(IVIM_DSTAR_FIX), m_FitDStar(true), m_Verbose(false) { this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfRequiredOutputs( 3 ); typename OutputImageType::Pointer outputPtr1 = OutputImageType::New(); this->SetNthOutput(0, outputPtr1.GetPointer()); typename OutputImageType::Pointer outputPtr2 = OutputImageType::New(); this->SetNthOutput(1, outputPtr2.GetPointer()); typename OutputImageType::Pointer outputPtr3 = OutputImageType::New(); this->SetNthOutput(2, outputPtr3.GetPointer()); } template< class TIn, class TOut> void DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::BeforeThreadedGenerateData() { // Input must be an itk::VectorImage. std::string gradientImageClassName( this->ProcessObject::GetInput(0)->GetNameOfClass()); if ( strcmp(gradientImageClassName.c_str(),"VectorImage") != 0 ) { itkExceptionMacro( << "There is only one Gradient image. I expect that to be a VectorImage. " << "But its of type: " << gradientImageClassName ); } // Compute the indicies of the baseline images and gradient images // If no b=0 mm/s² gradients ar found, the next lowest b-value is used. GradientDirectionContainerType::ConstIterator gdcit = this->m_GradientDirectionContainer->Begin(); double minNorm = itk::NumericTraits::max(); while( gdcit != this->m_GradientDirectionContainer->End() ) { double norm = gdcit.Value().one_norm(); if (normm_GradientDirectionContainer->Begin(); while( gdcit != this->m_GradientDirectionContainer->End() ) { if(gdcit.Value().one_norm() <= minNorm) { m_Snap.baselineind.push_back(gdcit.Index()); } else { m_Snap.gradientind.push_back(gdcit.Index()); double twonorm = gdcit.Value().two_norm(); m_Snap.bvals.push_back( m_BValue*twonorm*twonorm ); } ++gdcit; } if (m_Snap.gradientind.size()==0) itkExceptionMacro("Only one b-value supplied. At least two needed for IVIM fit."); // check sind die grad und base gleichlang? alle grad gerade und base ungerade? dann iterierende aufnahme!! m_Snap.iterated_sequence = false; if(m_Snap.baselineind.size() == m_Snap.gradientind.size()) { int size = m_Snap.baselineind.size(); int sum_b = 0, sum_g = 0; for(int i=0; im_BThres) { m_Snap.high_indices.push_back(i); } } } m_Snap.Nhigh = m_Snap.high_indices.size(); m_Snap.high_bvalues.set_size(m_Snap.Nhigh); m_Snap.high_meas.set_size(m_Snap.Nhigh); for(int i=0; i MeasAndBvals DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::ApplyS0Threshold(vnl_vector &meas, vnl_vector &bvals) { std::vector newmeas; std::vector newbvals; int N = meas.size(); for(int i=0; i void DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - int ) + ThreadIdType ) { typename OutputImageType::Pointer outputImage = - static_cast< OutputImageType * >(this->ProcessObject::GetOutput()); + static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput()); ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread); oit.GoToBegin(); typename OutputImageType::Pointer dImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(1)); ImageRegionIterator< OutputImageType > oit1(dImage, outputRegionForThread); oit1.GoToBegin(); typename OutputImageType::Pointer dstarImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(2)); ImageRegionIterator< OutputImageType > oit2(dstarImage, outputRegionForThread); oit2.GoToBegin(); typedef ImageRegionConstIterator< InputImageType > InputIteratorType; typedef typename InputImageType::PixelType InputVectorType; typename InputImageType::Pointer inputImagePointer = NULL; // Would have liked a dynamic_cast here, but seems SGI doesn't like it // The enum will DiffusionIntravoxelIncoherentMotionReconstructionImageFilterensure that an inappropriate cast is not done inputImagePointer = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); InputIteratorType iit(inputImagePointer, outputRegionForThread ); iit.GoToBegin(); // init internal vector image for regularized fit m_InternalVectorImage = VectorImageType::New(); m_InternalVectorImage->SetSpacing( inputImagePointer->GetSpacing() ); // Set the image spacing m_InternalVectorImage->SetOrigin( inputImagePointer->GetOrigin() ); // Set the image origin m_InternalVectorImage->SetDirection( inputImagePointer->GetDirection() ); // Set the image direction m_InternalVectorImage->SetRegions( inputImagePointer->GetLargestPossibleRegion() ); m_InitialFitImage = InitialFitImageType::New(); m_InitialFitImage->SetSpacing( inputImagePointer->GetSpacing() ); // Set the image spacing m_InitialFitImage->SetOrigin( inputImagePointer->GetOrigin() ); // Set the image origin m_InitialFitImage->SetDirection( inputImagePointer->GetDirection() ); // Set the image direction m_InitialFitImage->SetRegions( inputImagePointer->GetLargestPossibleRegion() ); if(m_Method == IVIM_REGULARIZED) { m_InternalVectorImage->SetVectorLength(m_Snap.Nhigh); m_InternalVectorImage->Allocate(); VectorImageType::PixelType varvec(m_Snap.Nhigh); for(int i=0; iFillBuffer(varvec); m_InitialFitImage->Allocate(); InitialFitImageType::PixelType vec; vec[0] = 0.5; vec[1] = 0.01; vec[2]=0.001; m_InitialFitImage->FillBuffer(vec); } typedef itk::ImageRegionIterator VectorIteratorType; VectorIteratorType vecit(m_InternalVectorImage, outputRegionForThread ); vecit.GoToBegin(); typedef itk::ImageRegionIterator InitIteratorType; InitIteratorType initit(m_InitialFitImage, outputRegionForThread ); initit.GoToBegin(); while( !iit.IsAtEnd() ) { InputVectorType measvec = iit.Get(); typename NumericTraits::AccumulateType b0 = NumericTraits::Zero; m_Snap.meas.set_size(m_Snap.N); m_Snap.allmeas.set_size(m_Snap.N); if(!m_Snap.iterated_sequence) { // Average the baseline image pixels for(unsigned int i = 0; i < m_Snap.baselineind.size(); ++i) { b0 += measvec[m_Snap.baselineind[i]]; } if(m_Snap.baselineind.size()) b0 /= m_Snap.baselineind.size(); // measurement vector for(int i = 0; i < m_Snap.N; ++i) { m_Snap.allmeas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001); if(measvec[m_Snap.gradientind[i]] > m_S0Thres) { m_Snap.meas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001); } else { m_Snap.meas[i] = IVIM_FOO; } } } else { // measurement vector for(int i = 0; i < m_Snap.N; ++i) { b0 = measvec[m_Snap.baselineind[i]]; m_Snap.allmeas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001); if(measvec[m_Snap.gradientind[i]] > m_S0Thres) { m_Snap.meas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001); } else { m_Snap.meas[i] = IVIM_FOO; } } } m_Snap.currentF = 0; m_Snap.currentD = 0; m_Snap.currentDStar = 0; switch(m_Method) { case IVIM_D_THEN_DSTAR: { for(int i=0; i x_donly(2); x_donly[0] = 0.001; x_donly[1] = 0.1; // f 0.1 Dstar 0.01 D 0.001 vnl_levenberg_marquardt lm_donly(f_donly); lm_donly.set_f_tolerance(0.0001); lm_donly.minimize(x_donly); m_Snap.currentD = x_donly[0]; m_Snap.currentF = x_donly[1]; if(m_FitDStar) { MeasAndBvals input2 = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues); m_Snap.bvals2 = input2.bvals; m_Snap.meas2 = input2.meas; if (input2.N < 2) break; IVIM_dstar_only f_dstar_only(input2.N,m_Snap.currentD,m_Snap.currentF); f_dstar_only.set_bvalues(input2.bvals); f_dstar_only.set_measurements(input2.meas); vnl_vector< double > x_dstar_only(1); vnl_vector< double > fx_dstar_only(input2.N); double opt = 1111111111111111.0; int opt_idx = -1; int num_its = 100; double min_val = .001; double max_val = .15; for(int i=0; i x_fixd(2); // x_fixd[0] = 0.1; // x_fixd[1] = 0.01; // // f 0.1 Dstar 0.01 D 0.001 // vnl_levenberg_marquardt lm_fixd(f_fixd); // lm_fixd.set_f_tolerance(0.0001); // lm_fixd.minimize(x_fixd); // m_Snap.currentF = x_fixd[0]; // m_Snap.currentDStar = x_fixd[1]; } break; } case IVIM_DSTAR_FIX: { MeasAndBvals input = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues); m_Snap.bvals1 = input.bvals; m_Snap.meas1 = input.meas; if (input.N < 2) break; IVIM_fixdstar f_fixdstar(input.N,m_DStar); f_fixdstar.set_bvalues(input.bvals); f_fixdstar.set_measurements(input.meas); vnl_vector< double > x(2); x[0] = 0.1; x[1] = 0.001; // f 0.1 Dstar 0.01 D 0.001 vnl_levenberg_marquardt lm(f_fixdstar); lm.set_f_tolerance(0.0001); lm.minimize(x); m_Snap.currentF = x[0]; m_Snap.currentD = x[1]; m_Snap.currentDStar = m_DStar; break; } case IVIM_FIT_ALL: { MeasAndBvals input = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues); m_Snap.bvals1 = input.bvals; m_Snap.meas1 = input.meas; if (input.N < 3) break; IVIM_3param f_3param(input.N); f_3param.set_bvalues(input.bvals); f_3param.set_measurements(input.meas); vnl_vector< double > x(3); x[0] = 0.1; x[1] = 0.001; x[2] = 0.01; // f 0.1 Dstar 0.01 D 0.001 vnl_levenberg_marquardt lm(f_3param); lm.set_f_tolerance(0.0001); lm.minimize(x); m_Snap.currentF = x[0]; m_Snap.currentD = x[1]; m_Snap.currentDStar = x[2]; break; } case IVIM_LINEAR_D_THEN_F: { // // neglect zero-measurements // bool zero = false; // for(int i=0; i X(input.N,2); for(int i=0; i XX = X.transpose() * X; vnl_symmetric_eigensystem eigs(XX); vnl_vector eig; if(eigs.get_eigenvalue(0) > eigs.get_eigenvalue(1)) eig = eigs.get_eigenvector(0); else eig = eigs.get_eigenvector(1); m_Snap.currentF = 1 - exp( meas_m - bval_m*(eig(1)/eig(0)) ); m_Snap.currentD = -eig(1)/eig(0); if(m_FitDStar) { MeasAndBvals input2 = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues); m_Snap.bvals2 = input2.bvals; m_Snap.meas2 = input2.meas; if (input2.N < 2) break; IVIM_dstar_only f_dstar_only(input2.N,m_Snap.currentD,m_Snap.currentF); f_dstar_only.set_bvalues(input2.bvals); f_dstar_only.set_measurements(input2.meas); vnl_vector< double > x_dstar_only(1); vnl_vector< double > fx_dstar_only(input2.N); double opt = 1111111111111111.0; int opt_idx = -1; int num_its = 100; double min_val = .001; double max_val = .15; for(int i=0; i " << DStar; // x_dstar_only[0] = 0.01; // // f 0.1 Dstar 0.01 D 0.001 // vnl_levenberg_marquardt lm_dstar_only(f_dstar_only); // lm_dstar_only.set_f_tolerance(0.0001); // lm_dstar_only.minimize(x_dstar_only); // DStar = x_dstar_only[0]; break; } case IVIM_REGULARIZED: { //m_Snap.high_meas, m_Snap.high_bvalues; for(int i=0; i x_donly(2); x_donly[0] = 0.001; x_donly[1] = 0.1; if(input.N >= 2) { IVIM_d_and_f f_donly(input.N); f_donly.set_bvalues(input.bvals); f_donly.set_measurements(input.meas); //MITK_INFO << "initial fit N=" << input.N << ", min-b = " << input.bvals[0] << ", max-b = " << input.bvals[input.N-1]; vnl_levenberg_marquardt lm_donly(f_donly); lm_donly.set_f_tolerance(0.0001); lm_donly.minimize(x_donly); } typename InitialFitImageType::PixelType initvec; initvec[0] = x_donly[1]; initvec[1] = x_donly[0]; initit.Set(initvec); //MITK_INFO << "Init vox " << initit.GetIndex() << " with " << initvec[0] << "; " << initvec[1]; ++initit; int N = m_Snap.high_meas.size(); typename VectorImageType::PixelType vec(N); for(int i=0; i void DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::AfterThreadedGenerateData() { if(m_Method == IVIM_REGULARIZED) { typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput()); ImageRegionIterator< OutputImageType > oit0(outputImage, outputImage->GetLargestPossibleRegion()); oit0.GoToBegin(); typename OutputImageType::Pointer dImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(1)); ImageRegionIterator< OutputImageType > oit1(dImage, dImage->GetLargestPossibleRegion()); oit1.GoToBegin(); typename OutputImageType::Pointer dstarImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(2)); ImageRegionIterator< OutputImageType > oit2(dstarImage, dstarImage->GetLargestPossibleRegion()); oit2.GoToBegin(); typedef itk::RegularizedIVIMReconstructionFilter RegFitType; RegFitType::Pointer filter = RegFitType::New(); filter->SetInput(m_InitialFitImage); filter->SetReferenceImage(m_InternalVectorImage); filter->SetBValues(m_Snap.high_bvalues); filter->SetNumberIterations(m_NumberIterations); filter->SetNumberOfThreads(1); filter->SetLambda(m_Lambda); filter->Update(); typename RegFitType::OutputImageType::Pointer outimg = filter->GetOutput(); ImageRegionConstIterator< RegFitType::OutputImageType > iit(outimg, outimg->GetLargestPossibleRegion()); iit.GoToBegin(); while( !iit.IsAtEnd() ) { double f = iit.Get()[0]; IVIM_CEIL( f, 0.0, 1.0 ); oit0.Set( myround(f * 100.0) ); oit1.Set( myround(iit.Get()[1] * 10000.0) ); oit2.Set( myround(iit.Get()[2] * 1000.0) ); if(!m_Verbose) { // report the middle voxel if( iit.GetIndex()[0] == m_CrossPosition[0] && iit.GetIndex()[1] == m_CrossPosition[1] && iit.GetIndex()[2] == m_CrossPosition[2] ) { m_Snap.currentF = f; m_Snap.currentD = iit.Get()[1]; m_Snap.currentDStar = iit.Get()[2]; m_Snap.allmeas = m_tmp_allmeas; MITK_INFO << "setting " << f << ";" << iit.Get()[1] << ";" << iit.Get()[2]; } } ++oit0; ++oit1; ++oit2; ++iit; } } } template< class TIn, class TOut> double DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::myround(double number) { return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5); } template< class TIn, class TOut> void DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::SetGradientDirections( GradientDirectionContainerType *gradientDirection ) { this->m_GradientDirectionContainer = gradientDirection; this->m_NumberOfGradientDirections = gradientDirection->Size(); } template< class TIn, class TOut> void DiffusionIntravoxelIncoherentMotionReconstructionImageFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); if ( m_GradientDirectionContainer ) { os << indent << "GradientDirectionContainer: " << m_GradientDirectionContainer << std::endl; } else { os << indent << "GradientDirectionContainer: (Gradient directions not set)" << std::endl; } } } #endif // __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_cpp diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h index cd6f77e29a..00f8c40cea 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h @@ -1,380 +1,380 @@ /*=================================================================== 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 __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h #define __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h #include "itkImageToImageFilter.h" //#include "vnl/vnl_matrix.h" #include "vnl/vnl_vector_fixed.h" #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_svd.h" #include "itkVectorContainer.h" #include "itkVectorImage.h" //#include "QuadProg.h" #include "itkVectorImage.h" #include "vnl/vnl_least_squares_function.h" #include "vnl/algo/vnl_levenberg_marquardt.h" #include "vnl/vnl_math.h" #define IVIM_CEIL(val,u,o) (val) = \ ( (val) < (u) ) ? ( (u) ) : ( ( (val)>(o) ) ? ( (o) ) : ( (val) ) ); namespace itk{ /** baseclass for IVIM fitting algorithms */ struct IVIM_base { void set_measurements(const vnl_vector& x) { measurements.set_size(x.size()); measurements.copy_in(x.data_block()); } void set_bvalues(const vnl_vector& x) { bvalues.set_size(x.size()); bvalues.copy_in(x.data_block()); } vnl_vector measurements; vnl_vector bvalues; int N; }; /** Fitt all three parameters */ struct IVIM_3param : public IVIM_base, vnl_least_squares_function { IVIM_3param(unsigned int number_of_measurements) : vnl_least_squares_function(3, number_of_measurements, no_gradient) { N = get_number_of_residuals(); } void f(const vnl_vector& x, vnl_vector& fx) { double ef = x[0]; double D = x[1]; double Dstar = x[2]; for(int s=0; s& x, vnl_vector& fx) { double ef = x[0]; double D = x[1]; for(int s=0; s& x, vnl_vector& fx) { double D = x[0]; double f = x[1]; for(int s=0; s& x, vnl_vector& fx) { double ef = x[0]; double Dstar = x[1]; for(int s=0; s& x, vnl_vector& fx) { double Dstar = x[0]; for(int s=0; s meas; vnl_vector bvals; int N; }; /** \class DiffusionIntravoxelIncoherentMotionReconstructionImageFilter */ template< class TInputPixelType, class TOutputPixelType> class DiffusionIntravoxelIncoherentMotionReconstructionImageFilter : public ImageToImageFilter< VectorImage< TInputPixelType, 3 >, Image< TOutputPixelType, 3 > > { public: struct IVIMSnapshot { double currentF; double currentFunceiled; double currentD; double currentDStar; bool iterated_sequence; // wether each measurement has its own b0-acqu. std::vector baselineind; // baseline image indicies int N; // total number of measurements std::vector gradientind; // gradient image indicies std::vector bvals; // b-values != 0 vnl_vector bvalues; // copy of bvalues != 0 vnl_vector meas; // all measurements, thresholded blanked out vnl_vector allmeas; // all measurements int Nhigh; // number of used measurements std::vector high_indices; // indices of used measurements vnl_vector high_bvalues; // bvals of used measurements vnl_vector high_meas; // used measurements vnl_vector meas1; vnl_vector bvals1; vnl_vector meas2; vnl_vector bvals2; }; enum IVIM_Method { IVIM_FIT_ALL, IVIM_DSTAR_FIX, IVIM_D_THEN_DSTAR, IVIM_LINEAR_D_THEN_F, IVIM_REGULARIZED }; typedef DiffusionIntravoxelIncoherentMotionReconstructionImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< VectorImage< TInputPixelType, 3>, Image< TOutputPixelType,3 > > Superclass; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(DiffusionIntravoxelIncoherentMotionReconstructionImageFilter, ImageToImageFilter); typedef TOutputPixelType OutputPixelType; typedef TInputPixelType InputPixelType; /** Reference image data, This image is aquired in the absence * of a diffusion sensitizing field gradient */ typedef typename Superclass::InputImageType InputImageType; typedef Image< OutputPixelType, 3 > OutputImageType; typedef typename Superclass::OutputImageRegionType OutputImageRegionType; /** Holds each magnetic field gradient used to acquire one DWImage */ typedef vnl_vector_fixed< double, 3 > GradientDirectionType; /** Container to hold gradient directions of the 'n' DW measurements */ typedef VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; // vector image typedefs for regularized fit typedef itk::VectorImage VectorImageType; typedef itk::Image, 3> InitialFitImageType; /** set method to add gradient directions and its corresponding * image. The image here is a VectorImage. The user is expected to pass the * gradient directions in a container. The ith element of the container * corresponds to the gradient direction of the ith component image the * VectorImage. For the baseline image, a vector of all zeros * should be set.*/ void SetGradientDirections( GradientDirectionContainerType * ); void SetBValue(double bval){m_BValue = bval;} void SetBThres(double bval){m_BThres = bval;} void SetS0Thres(double val){m_S0Thres = val;} void SetDStar(double dstar){m_DStar = dstar;} void SetFitDStar(bool fit){m_FitDStar = fit;} void SetVerbose(bool verbose){m_Verbose = verbose;} void SetNumberIterations(int num){m_NumberIterations = num;} void SetLambda(double lambda){m_Lambda = lambda;} void SetCrossPosition(typename InputImageType::IndexType crosspos){this->m_CrossPosition = crosspos;} void SetMethod(IVIM_Method method){m_Method = method;} IVIMSnapshot GetSnapshot(){return m_Snap;} /** Return the gradient direction. idx is 0 based */ virtual GradientDirectionType GetGradientDirection( unsigned int idx) const { if( idx >= m_NumberOfGradientDirections ) { itkExceptionMacro( << "Gradient direction " << idx << "does not exist" ); } return m_GradientDirectionContainer->ElementAt( idx+1 ); } protected: DiffusionIntravoxelIncoherentMotionReconstructionImageFilter(); ~DiffusionIntravoxelIncoherentMotionReconstructionImageFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; void BeforeThreadedGenerateData(); - void ThreadedGenerateData( const - OutputImageRegionType &outputRegionForThread, int); + void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, + ThreadIdType); void AfterThreadedGenerateData(); MeasAndBvals ApplyS0Threshold(vnl_vector &meas, vnl_vector &bvals); private: double myround(double number); /** container to hold gradient directions */ GradientDirectionContainerType::Pointer m_GradientDirectionContainer; /** Number of gradient measurements */ unsigned int m_NumberOfGradientDirections; double m_BValue; double m_BThres; double m_S0Thres; double m_DStar; IVIM_Method m_Method; typename OutputImageType::Pointer m_DMap; typename OutputImageType::Pointer m_DStarMap; bool m_FitDStar; IVIMSnapshot m_Snap; bool m_Verbose; typename VectorImageType::Pointer m_InternalVectorImage; typename InitialFitImageType::Pointer m_InitialFitImage; int m_NumberIterations; // for total variation vnl_vector m_tmp_allmeas; double m_Lambda; typename InputImageType::IndexType m_CrossPosition; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp" #endif #endif //__itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h index 9bea0276a6..6cd65d2296 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h @@ -1,102 +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. ===================================================================*/ /*=================================================================== This file is based heavily on a corresponding ITK filter. ===================================================================*/ #ifndef __itkDiffusionTensorPrincipalDirectionImageFilter_h_ #define __itkDiffusionTensorPrincipalDirectionImageFilter_h_ #include "DiffusionCoreExports.h" #include #include #include #include #include #include #include #include namespace itk{ /** \brief Extracts principal eigenvectors of the input tensors */ template< class TTensorPixelType, class TPDPixelType=float> class DiffusionTensorPrincipalDirectionImageFilter : public ImageToImageFilter< Image< DiffusionTensor3D, 3 >, Image< Vector< TPDPixelType, 3 >, 3 > > { public: typedef DiffusionTensorPrincipalDirectionImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< Image< DiffusionTensor3D, 3 >, Image< Vector< TPDPixelType, 3 >, 3 > > Superclass; /** Method for creation through the object factory. */ itkNewMacro(Self) /** Runtime information support. */ itkTypeMacro(DiffusionTensorPrincipalDirectionImageFilter, ImageToImageFilter) typedef TTensorPixelType TensorComponentType; typedef TPDPixelType DirectionPixelType; typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImageRegionType OutputImageRegionType; typedef itk::Image ItkUcharImgType; typedef vnl_vector_fixed< double, 3 > DirectionType; void SetImage( const InputImageType *image ); // input itkSetMacro( MaskImage, ItkUcharImgType::Pointer) itkSetMacro( NormalizeVectors, bool) // output itkGetMacro( OutputFiberBundle, mitk::FiberBundleX::Pointer) itkGetMacro( NumDirectionsImage, ItkUcharImgType::Pointer) protected: DiffusionTensorPrincipalDirectionImageFilter(); ~DiffusionTensorPrincipalDirectionImageFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; void BeforeThreadedGenerateData(); void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, ThreadIdType ); void AfterThreadedGenerateData(); private: bool m_NormalizeVectors; ///< Normalizes the output vector to length 1 mitk::FiberBundleX::Pointer m_OutputFiberBundle; ///< Vector field representation of the output vectors ItkUcharImgType::Pointer m_NumDirectionsImage; ///< Image containing the number of fiber directions per voxel ItkUcharImgType::Pointer m_MaskImage; ///< Extraction is only performed inside of the binary mask float m_MaxEigenvalue; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkDiffusionTensorPrincipalDirectionImageFilter.txx" #endif #endif //__itkDiffusionTensorPrincipalDirectionImageFilter_h_ diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStochasticTractographyFilter.h b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStochasticTractographyFilter.h index c8770d5a56..d9f5378022 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStochasticTractographyFilter.h +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkStochasticTractographyFilter.h @@ -1,305 +1,315 @@ /*=================================================================== 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 __itkStochasticTractographyFilter_h__ #define __itkStochasticTractographyFilter_h__ #include "itkImageToImageFilter.h" #include "vnl/vnl_random.h" #include "vnl/vnl_vector_fixed.h" #include "vnl/vnl_matrix.h" #include "itkArray.h" #include "itkVectorContainer.h" #include "vnl/algo/vnl_qr.h" #include "itkVariableLengthVector.h" #include "StochasticTracking/itkSlowPolyLineParametricPath.h" #include "itkSimpleFastMutexLock.h" #include "itkRealTimeClock.h" #include "itkDiffusionTensor3D.h" #include namespace itk{ /** * \brief Performs probabilistic streamline tracking on the input dwi. */ /**Types for Probability Distribution **/ typedef Image< Array< double >, 3 > ProbabilityDistributionImageType; template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage, class TOutputConnectivityImage > class ITK_EXPORT StochasticTractographyFilter : public ImageToImageFilter< TInputDWIImage, TOutputConnectivityImage >{ public: typedef StochasticTractographyFilter Self; typedef ImageToImageFilter< TInputDWIImage, TOutputConnectivityImage > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro(Self) itkTypeMacro( StochasticTractographyFilter, ImageToImageFilter ) /** Types for the DWI Input Image **/ typedef TInputDWIImage InputDWIImageType; /** Types for the Connectivity Output Image**/ typedef TOutputConnectivityImage OutputConnectivityImageType; /** Types for the Mask Image **/ typedef TInputWhiteMatterProbabilityImage InputWhiteMatterProbabilityImageType; /** Tract Types **/ typedef SlowPolyLineParametricPath< 3 > TractType; /** Types for the TractContainer **/ typedef VectorContainer< unsigned int, typename TractType::Pointer > TractContainerType; /** Types for Tensor Output Image **/ typedef Image< DiffusionTensor3D< double >, 3 > OutputTensorImageType; /** Types for the Image-wide Magnetic Field Gradient Directions **/ typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > GradientDirectionContainerType; /** Types for the Image-wide bValues **/ typedef double bValueType; typedef VectorContainer< unsigned int, bValueType > bValueContainerType; /** Types for the Measurement Frame of the Gradients **/ typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType; /** Type for the sample directions **/ typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > TractOrientationContainerType; /** the number of Tracts to generate **/ itkSetMacro( TotalTracts, unsigned int) itkGetMacro( TotalTracts, unsigned int) /** the maximum length of Tract **/ itkSetMacro( MaxTractLength, unsigned int ) itkGetMacro( MaxTractLength, unsigned int ) /** Set/Get bvalues **/ itkSetConstObjectMacro( bValues, bValueContainerType ) itkGetConstObjectMacro( bValues, bValueContainerType ) /** Set/Get of gradient directions **/ itkSetConstObjectMacro( Gradients, GradientDirectionContainerType ) itkGetConstObjectMacro( Gradients, GradientDirectionContainerType ) /** Set/Get the White Matter Probability Input image **/ /* At each voxel specifies the probability of a mylinated fiber existing at that location. This probability is interpreted to be the probability that a fiber tract passes through that region. */ itkSetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType) itkGetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType) //overide the built in set input function //we need to create a new cache everytime we change the input image //but we need to preserve it when the input image is the same - using Superclass::SetInput; - void SetInput( typename InputDWIImageType::Pointer dwiimagePtr ){ - Superclass::SetInput( dwiimagePtr ); + void SetPrimaryInput(DataObject *input) + { + typename InputDWIImageType::Pointer dwiimagePtr; + try + { + dwiimagePtr = dynamic_cast( input ); + } + catch(itk::ExceptionObject &e) + { + MITK_INFO << "wrong image type: " << e.what(); + throw; + } + Superclass::SetPrimaryInput( input ); //update the likelihood cache this->m_LikelihoodCachePtr = ProbabilityDistributionImageType::New(); this->m_LikelihoodCachePtr->CopyInformation( this->GetInput() ); this->m_LikelihoodCachePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() ); this->m_LikelihoodCachePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() ); this->m_LikelihoodCachePtr->Allocate(); this->m_CurrentLikelihoodCacheElements = 0; //update the likelihoodcache mutex image this->m_LikelihoodCacheMutexImagePtr = LikelihoodCacheMutexImageType::New(); this->m_LikelihoodCacheMutexImagePtr->CopyInformation( this->GetInput() ); this->m_LikelihoodCacheMutexImagePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() ); this->m_LikelihoodCacheMutexImagePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() ); this->m_LikelihoodCacheMutexImagePtr->Allocate(); } /** Set/Get the seed index **/ itkSetMacro( SeedIndex, typename InputDWIImageType::IndexType ) itkGetMacro( SeedIndex, typename InputDWIImageType::IndexType ) /** Set/Get the list of directions to sample **/ itkSetConstObjectMacro( SampleDirections, TractOrientationContainerType ) itkGetConstObjectMacro( SampleDirections, TractOrientationContainerType ) /** Set/Get the Measurement Frame **/ itkSetMacro( MeasurementFrame, MeasurementFrameType ) itkGetMacro( MeasurementFrame, MeasurementFrameType ) /** Set/Get the Maximum Likelihood Cache Size, the max num. of cached voxels **/ itkSetMacro( MaxLikelihoodCacheSize, unsigned int ) itkGetMacro( MaxLikelihoodCacheSize, unsigned int ) /** Get the Tracts that are generated **/ itkGetObjectMacro( OutputTractContainer, TractContainerType ) /** Get TensorImage **/ itkGetObjectMacro( OutputTensorImage, OutputTensorImageType ) void GenerateData(); void GenerateTractContainerOutput( void ); void GenerateTensorImageOutput( void ); protected: /** Convenience Types used only inside the filter **/ /**Types for the parameters of the Tensor Model **/ typedef vnl_vector_fixed< double, 7 > TensorModelParamType; /**Types for the parameters of the Constrained Model **/ typedef vnl_vector_fixed< double, 6 > ConstrainedModelParamType; /**Type to hold generated DWI values**/ typedef Image< VariableLengthVector< double >, 3 > DWIVectorImageType; /**Types for Probability Distribution **/ typedef Image< Array< double >, 3 > ProbabilityDistributionImageType; /** Types for the Image of Mutexes of the Likelihood distribution **/ typedef Image< SimpleFastMutexLock, 3 > LikelihoodCacheMutexImageType; StochasticTractographyFilter(); virtual ~StochasticTractographyFilter(); /** Load the default Sample Directions**/ void LoadDefaultSampleDirections( void ); /** Randomly chose a neighboring pixel weighted on distance **/ void ProbabilisticallyInterpolate( vnl_random& randomgenerator, const TractType::ContinuousIndexType& cindex, typename InputDWIImageType::IndexType& index); /** Functions and data related to fitting the tensor model at each pixel **/ void UpdateGradientDirections(void); void UpdateTensorModelFittingMatrices( void ); void CalculateTensorModelParameters( const DWIVectorImageType::PixelType& dwivalues, vnl_diag_matrix& W, TensorModelParamType& tensormodelparams); void CalculateConstrainedModelParameters( const TensorModelParamType& tensormodelparams, ConstrainedModelParamType& constrainedmodelparams); void CalculateNoiseFreeDWIFromConstrainedModel( const ConstrainedModelParamType& constrainedmodelparams, DWIVectorImageType::PixelType& noisefreedwi); void CalculateResidualVariance( const DWIVectorImageType::PixelType& noisydwi, const DWIVectorImageType::PixelType& noisefreedwi, const vnl_diag_matrix< double >& W, const unsigned int numberofparameters, double& residualvariance); void CalculateLikelihood( const DWIVectorImageType::PixelType &dwipixel, TractOrientationContainerType::ConstPointer orientations, ProbabilityDistributionImageType::PixelType& likelihood); void CalculatePrior( TractOrientationContainerType::Element v_prev, TractOrientationContainerType::ConstPointer orientations, ProbabilityDistributionImageType::PixelType& prior ); void CalculatePosterior( const ProbabilityDistributionImageType::PixelType& likelihood, const ProbabilityDistributionImageType::PixelType& prior, ProbabilityDistributionImageType::PixelType& posterior); void SampleTractOrientation( vnl_random& randomgenerator, const ProbabilityDistributionImageType::PixelType& posterior, TractOrientationContainerType::ConstPointer orientations, TractOrientationContainerType::Element& choosendirection ); void StochasticTractGeneration( typename InputDWIImageType::ConstPointer dwiimagePtr, typename InputWhiteMatterProbabilityImageType::ConstPointer maskimagePtr, typename InputDWIImageType::IndexType seedindex, unsigned long randomseed, TractType::Pointer tract ); /** Callback routine used by the threading library. This routine just calls the ThreadedGenerateData method after setting the correct region for this thread. **/ static ITK_THREAD_RETURN_TYPE StochasticTractGenerationCallback( void *arg ); struct StochasticTractGenerationCallbackStruct{ Pointer Filter; }; /** Thread Safe Function to check/update an entry in the likelihood cache **/ ProbabilityDistributionImageType::PixelType& AccessLikelihoodCache( typename InputDWIImageType::IndexType index ); /** Thread Safe Function to delegate a tract and obtain a randomseed to start tracking **/ bool DelegateTract(unsigned long& randomseed); /** Function to write a tract to the connectivity map **/ void TractContainerToConnectivityMap(TractContainerType::Pointer tractcontainer); /** Thread Safe Function to store a tract to a TractContainer **/ void StoreTract(TractType::Pointer tract); /** Randomly samples the existence of a fiber tract in the current voxel **/ bool FiberExistenceTest( vnl_random& randomgenerator, typename InputWhiteMatterProbabilityImageType::ConstPointer wmpimage, typename InputWhiteMatterProbabilityImageType::IndexType index ); MeasurementFrameType m_MeasurementFrame; LikelihoodCacheMutexImageType::Pointer m_LikelihoodCacheMutexImagePtr; unsigned int m_TotalTracts; unsigned int m_MaxTractLength; GradientDirectionContainerType::ConstPointer m_Gradients; GradientDirectionContainerType::Pointer m_TransformedGradients; bValueContainerType::ConstPointer m_bValues; typename InputDWIImageType::IndexType m_SeedIndex; TractOrientationContainerType::ConstPointer m_SampleDirections; //these will be the same for every pixel in the image so //go ahead and do a QR decomposition to optimize the //LS fitting process for estimating the weighing matrix W //in this case we solve instead: //R*Beta = Q'logPhi vnl_matrix< double >* m_A; vnl_qr< double >* m_Aqr; ProbabilityDistributionImageType::Pointer m_LikelihoodCachePtr; unsigned long m_MaxLikelihoodCacheSize; //in Megabytes unsigned long m_MaxLikelihoodCacheElements; //in Elements (Voxels) unsigned long m_CurrentLikelihoodCacheElements; SimpleFastMutexLock m_LikelihoodCacheMutex; RealTimeClock::Pointer m_ClockPtr; unsigned int m_TotalDelegatedTracts; SimpleFastMutexLock m_TotalDelegatedTractsMutex; //unsigned long m_RandomSeed; SimpleFastMutexLock m_OutputImageMutex; TractContainerType::Pointer m_OutputTractContainer; SimpleFastMutexLock m_OutputTractContainerMutex; OutputTensorImageType::Pointer m_OutputTensorImage; vnl_random m_RandomGenerator; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkStochasticTractographyFilter.txx" #include "StochasticTracking/itkStochasticTractographyFilter_SD.txx" #endif #endif diff --git a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.h b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.h index ded47c327a..af2d0217c5 100644 --- a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.h +++ b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.h @@ -1,152 +1,152 @@ /*=================================================================== 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 __itkRegularizedIVIMLocalVariationImageFilter_h #define __itkRegularizedIVIMLocalVariationImageFilter_h #include "itkImageToImageFilter.h" #include "itkImage.h" namespace itk { template class IVIMSquaredEuclideanMetric { public: static double Calc(TPixelType p) { return p*p; } }; template<> class IVIMSquaredEuclideanMetric > { public: static double Calc(itk::Vector p) { return p[1]*p[1]; } }; template<> class IVIMSquaredEuclideanMetric > { public: static double Calc(itk::VariableLengthVector p) { return p.GetSquaredNorm(); } }; template<> class IVIMSquaredEuclideanMetric > { public: static double Calc(itk::VariableLengthVector p) { return p.GetSquaredNorm(); } }; /** \class RegularizedIVIMLocalVariationImageFilter * \brief Calculates the local variation in each pixel * * Reference: Tony F. Chan et al., The digital TV filter and nonlinear denoising * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * * \ingroup IntensityImageFilters */ template class RegularizedIVIMLocalVariationImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Extract dimension from input and output image. */ itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); /** Convenient typedefs for simplifying declarations. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; /** Standard class typedefs. */ typedef RegularizedIVIMLocalVariationImageFilter Self; typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(RegularizedIVIMLocalVariationImageFilter, ImageToImageFilter); /** Image typedef support. */ typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename InputImageType::SizeType InputSizeType; /** MedianImageFilter needs a larger input requested region than * the output requested region. As such, MedianImageFilter needs * to provide an implementation for GenerateInputRequestedRegion() * in order to inform the pipeline execution model. * * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); protected: RegularizedIVIMLocalVariationImageFilter(); virtual ~RegularizedIVIMLocalVariationImageFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; /** MedianImageFilter can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() * routine which is called for each processing thread. The output * image data is allocated automatically by the superclass prior to * calling ThreadedGenerateData(). ThreadedGenerateData can only * write to the portion of the output image specified by the * parameter "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - int threadId ); + ThreadIdType threadId ); private: RegularizedIVIMLocalVariationImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkRegularizedIVIMLocalVariationImageFilter.txx" #endif #endif //RegularizedIVIMLocalVariationImageFilter diff --git a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.txx b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.txx index 54acf9f02f..3acd73b82a 100644 --- a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.txx +++ b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMLocalVariationImageFilter.txx @@ -1,192 +1,192 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef _itkRegularizedIVIMLocalVariationImageFilter_txx #define _itkRegularizedIVIMLocalVariationImageFilter_txx #include "itkConstShapedNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIterator.h" #include "itkNeighborhoodAlgorithm.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkOffset.h" #include "itkProgressReporter.h" #include "itkVectorImage.h" #include #include namespace itk { template RegularizedIVIMLocalVariationImageFilter ::RegularizedIVIMLocalVariationImageFilter() {} template void RegularizedIVIMLocalVariationImageFilter ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError) { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // get pointers to the input and output typename Superclass::InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput() ); typename Superclass::OutputImagePointer outputPtr = this->GetOutput(); if ( !inputPtr || !outputPtr ) { return; } // get a copy of the input requested region (should equal the output // requested region) typename TInputImage::RegionType inputRequestedRegion; inputRequestedRegion = inputPtr->GetRequestedRegion(); // pad the input requested region by 1 inputRequestedRegion.PadByRadius( 1 ); // crop the input requested region at the input's largest possible region if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) { inputPtr->SetRequestedRegion( inputRequestedRegion ); return; } else { // Couldn't crop the region (requested region is outside the largest // possible region). Throw an exception. // store what we tried to request (prior to trying to crop) inputPtr->SetRequestedRegion( inputRequestedRegion ); // build an exception InvalidRequestedRegionError e(__FILE__, __LINE__); e.SetLocation(ITK_LOCATION); e.SetDescription("Requested region outside possible region."); e.SetDataObject(inputPtr); throw e; } } template< class TInputImage, class TOutputImage> void RegularizedIVIMLocalVariationImageFilter< TInputImage, TOutputImage> ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - int threadId) + ThreadIdType threadId) { // Allocate output typename OutputImageType::Pointer output = this->GetOutput(); typename InputImageType::ConstPointer input = this->GetInput(); itk::Size size; for( int i=0; i bC; typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType faceList = bC(input, outputRegionForThread, size); // support progress methods/callbacks ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels()); ZeroFluxNeumannBoundaryCondition nbc; std::vector pixels; // Process each of the boundary faces. These are N-d regions which border // the edge of the buffer. for ( typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType::iterator fit=faceList.begin(); fit != faceList.end(); ++fit) { // iterators over output and input ImageRegionIterator output_image_it(output, *fit); ImageRegionConstIterator input_image_it(input.GetPointer(), *fit); // neighborhood iterator for input image ConstShapedNeighborhoodIterator input_image_neighbors_it(size, input, *fit); typename ConstShapedNeighborhoodIterator:: OffsetType offset; input_image_neighbors_it.OverrideBoundaryCondition(&nbc); input_image_neighbors_it.ClearActiveList(); for(int i=0; i:: ConstIterator input_neighbors_it; for (input_neighbors_it = input_image_neighbors_it.Begin(); ! input_neighbors_it.IsAtEnd(); input_neighbors_it++) { typename TInputImage::PixelType diffVec = input_neighbors_it.Get()-input_image_it.Get(); locVariation += IVIMSquaredEuclideanMetric ::Calc(diffVec); } locVariation = sqrt(locVariation + 0.0001); output_image_it.Set(locVariation); // update iterators ++input_image_neighbors_it; ++output_image_it; ++input_image_it; // report progress progress.CompletedPixel(); } } } /** * Standard "PrintSelf" method */ template void RegularizedIVIMLocalVariationImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif //_itkRegularizedIVIMLocalVariationImageFilter_txx diff --git a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.h b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.h index 42701e4c20..3e5dbc7faf 100644 --- a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.h +++ b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.h @@ -1,141 +1,141 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __itkRegularizedIVIMReconstructionSingleIteration_h #define __itkRegularizedIVIMReconstructionSingleIteration_h #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkVectorImage.h" namespace itk { /** \class RegularizedIVIMReconstructionSingleIteration * \brief Applies a total variation denoising filter to an image * * Reference: Tony F. Chan et al., The digital TV filter and nonlinear denoising * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * * \ingroup IntensityImageFilters */ template class RegularizedIVIMReconstructionSingleIteration : public ImageToImageFilter< itk::Image, 3>, itk::Image, 3> > { public: /** Convenient typedefs for simplifying declarations. */ typedef itk::Image, 3> InputImageType; typedef itk::Image, 3> OutputImageType; typedef itk::VectorImage RefImageType; /** Extract dimension from input and output image. */ itkStaticConstMacro(InputImageDimension, unsigned int, InputImageType::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, OutputImageType::ImageDimension); typedef itk::Image LocalVariationImageType; /** Standard class typedefs. */ typedef RegularizedIVIMReconstructionSingleIteration Self; typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(RegularizedIVIMReconstructionSingleIteration, ImageToImageFilter); /** Image typedef support. */ typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename InputImageType::SizeType InputSizeType; /** A larger input requested region than * the output requested region is required. * Therefore, an implementation for GenerateInputRequestedRegion() * is provided. * * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); itkSetMacro(Lambda, double); itkGetMacro(Lambda, double); void SetBValues(vnl_vector bvals) { this->m_BValues = bvals; } vnl_vector GetBValues() { return this->m_BValues; } void SetOriginalImage(RefImageType* in) { this->m_OriginalImage = in; } typename RefImageType::Pointer GetOriginialImage() { return this->m_OriginalImage; } protected: RegularizedIVIMReconstructionSingleIteration(); virtual ~RegularizedIVIMReconstructionSingleIteration() {} void PrintSelf(std::ostream& os, Indent indent) const; /** MedianImageFilter can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() * routine which is called for each processing thread. The output * image data is allocated automatically by the superclass prior to * calling ThreadedGenerateData(). ThreadedGenerateData can only * write to the portion of the output image specified by the * parameter "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - int threadId ); + ThreadIdType threadId ); void BeforeThreadedGenerateData(); typename LocalVariationImageType::Pointer m_LocalVariation; typename RefImageType::Pointer m_OriginalImage; double m_Lambda; vnl_vector m_BValues; private: RegularizedIVIMReconstructionSingleIteration(const Self&); void operator=(const Self&); }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkRegularizedIVIMReconstructionSingleIteration.txx" #endif #endif //__itkRegularizedIVIMReconstructionSingleIteration__ diff --git a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.txx b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.txx index 09d0e5d527..adc1d08ac1 100644 --- a/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.txx +++ b/Modules/DiffusionImaging/Quantification/Algorithms/itkRegularizedIVIMReconstructionSingleIteration.txx @@ -1,310 +1,310 @@ /*=================================================================== 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 _itkRegularizedIVIMReconstructionSingleIteration_txx #define _itkRegularizedIVIMReconstructionSingleIteration_txx // itk includes #include "itkConstShapedNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIterator.h" #include "itkNeighborhoodAlgorithm.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkOffset.h" #include "itkProgressReporter.h" #include "itkRegularizedIVIMLocalVariationImageFilter.h" // other includes #include #include #define IVIM_FOO -100000 namespace itk { /** * constructor */ template RegularizedIVIMReconstructionSingleIteration ::RegularizedIVIMReconstructionSingleIteration() { m_Lambda = 1.0; m_LocalVariation = LocalVariationImageType::New(); } /** * generate requested region */ template void RegularizedIVIMReconstructionSingleIteration ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError) { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // get pointers to the input and output typename Superclass::InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); typename Superclass::OutputImagePointer outputPtr = this->GetOutput(); if ( !inputPtr || !outputPtr ) { return; } // get a copy of the input requested region (should equal the output // requested region) typename InputImageType::RegionType inputRequestedRegion; inputRequestedRegion = inputPtr->GetRequestedRegion(); // pad the input requested region by 1 inputRequestedRegion.PadByRadius( 1 ); // crop the input requested region at the input's largest possible region if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) { inputPtr->SetRequestedRegion( inputRequestedRegion ); return; } else { // Couldn't crop the region (requested region is outside the largest // possible region). Throw an exception. // store what we tried to request (prior to trying to crop) inputPtr->SetRequestedRegion( inputRequestedRegion ); // build an exception InvalidRequestedRegionError e(__FILE__, __LINE__); e.SetLocation(ITK_LOCATION); e.SetDescription("Requested region outside possible region."); e.SetDataObject(inputPtr); throw e; } } /** * generate output */ template void RegularizedIVIMReconstructionSingleIteration ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - int threadId) + ThreadIdType) { typename OutputImageType::Pointer output = this->GetOutput(); typename InputImageType::ConstPointer input = this->GetInput(); // Find the data-set boundary "faces" itk::Size size; for( int i=0; i bC; typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType faceList = bC(input, outputRegionForThread, size); NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator lv_bC; typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType lv_faceList = lv_bC(m_LocalVariation, outputRegionForThread, size); ZeroFluxNeumannBoundaryCondition nbc; ZeroFluxNeumannBoundaryCondition lv_nbc; std::vector ws; std::vector hs; typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType::iterator lv_fit=lv_faceList.begin(); // Process each of the boundary faces. These are N-d regions which border // the edge of the buffer. for ( typename NeighborhoodAlgorithm:: ImageBoundaryFacesCalculator::FaceListType::iterator fit=faceList.begin(); fit != faceList.end(); ++fit) { // iterators over output, input, original and local variation image ImageRegionIterator output_image_it = ImageRegionIterator(output, *fit); ImageRegionConstIterator input_image_it = ImageRegionConstIterator(input, *fit); ImageRegionConstIterator orig_image_it = ImageRegionConstIterator(m_OriginalImage, *fit); ImageRegionConstIterator loc_var_image_it = ImageRegionConstIterator( m_LocalVariation, *fit); // neighborhood in input image ConstShapedNeighborhoodIterator input_image_neighbors_it(size, input, *fit); typename ConstShapedNeighborhoodIterator:: OffsetType offset; input_image_neighbors_it.OverrideBoundaryCondition(&nbc); input_image_neighbors_it.ClearActiveList(); for(int i=0; i loc_var_image_neighbors_it(size, m_LocalVariation, *lv_fit); loc_var_image_neighbors_it.OverrideBoundaryCondition(&lv_nbc); loc_var_image_neighbors_it.ClearActiveList(); for(int i=0; i:: ConstIterator loc_var_neighbors_it; for (loc_var_neighbors_it = loc_var_image_neighbors_it.Begin(); ! loc_var_neighbors_it.IsAtEnd(); loc_var_neighbors_it++) { // w_alphabeta(u) = // 1 / ||nabla_alpha(u)||_a + 1 / ||nabla_beta(u)||_a ws[count] = locvar_alpha_inv + (1.0/(double)loc_var_neighbors_it.Get()); wsum += ws[count++]; //MITK_INFO << "nb var: " << count << ": " << loc_var_neighbors_it.Get(); } //MITK_INFO << "wsum: " << wsum; // h_alphaalpha * u_alpha^zero typename RefImageType::PixelType orig = orig_image_it.Get(); // vnl_vector estim(orig.GetSize()); // vnl_matrix diff(orig.GetSize(),1); // vnl_matrix estimdash(orig.GetSize(),2); vnl_vector_fixed step; step[0] = 0; step[1]=0; - for(int ind=0; ind:: ConstIterator input_neighbors_it; for (input_neighbors_it = input_image_neighbors_it.Begin(); ! input_neighbors_it.IsAtEnd(); input_neighbors_it++) { step[1] += (input_neighbors_it.Get()[1] - input_image_it.Get()[1]) * (ws[count++] / (m_Lambda+wsum)); } //MITK_INFO << "stepfinal: " << step[0] << "; " << step[1]; // set output result OutputPixelType out; out[0] = input_image_it.Get()[0] + .001*step[0]; out[1] = input_image_it.Get()[1] + .00001*step[1]; output_image_it.Set( out ); //MITK_INFO << "(" << input_image_it.Get()[0] << " ; " << input_image_it.Get()[1] << ") => (" << out[0] << " ; " << out[1] << ")"; // increment iterators ++output_image_it; ++input_image_it; ++orig_image_it; ++loc_var_image_it; ++input_image_neighbors_it; ++loc_var_image_neighbors_it; } ++lv_fit; } } /** * first calculate local variation in the image */ template void RegularizedIVIMReconstructionSingleIteration ::BeforeThreadedGenerateData() { typedef typename itk::RegularizedIVIMLocalVariationImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(this->GetInput(0)); filter->SetNumberOfThreads(this->GetNumberOfThreads()); filter->Update(); this->m_LocalVariation = filter->GetOutput(); } /** * Standard "PrintSelf" method */ template void RegularizedIVIMReconstructionSingleIteration ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp index 2dcdc583dd..7e816cd56a 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataSequentialPlayer.cpp @@ -1,225 +1,226 @@ /*=================================================================== 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 "mitkNavigationDataSequentialPlayer.h" #include //for the pause #include #include //Exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" mitk::NavigationDataSequentialPlayer::NavigationDataSequentialPlayer() : mitk::NavigationDataPlayerBase() , m_Doc(new TiXmlDocument) , m_DataElem(0) , m_CurrentElem(0) , m_Repeat(false) , m_NumberOfSnapshots(0) , m_LastGoTo(0) { } mitk::NavigationDataSequentialPlayer::~NavigationDataSequentialPlayer() { delete m_Doc; } void mitk::NavigationDataSequentialPlayer::ReinitXML() { m_DataElem = m_Doc->FirstChildElement("Data"); int toolcount; if(!m_DataElem) { MITK_WARN << "Data element not found"; mitkThrowException(mitk::IGTException) << "Data element not found"; } else { m_DataElem->QueryIntAttribute("ToolCount", &toolcount); - this->SetNumberOfOutputs(toolcount); + this->SetNumberOfRequiredOutputs(toolcount); mitk::NavigationData::Pointer emptyNd = mitk::NavigationData::New(); mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0); position.Fill(0.0); emptyNd->SetPosition(position); emptyNd->SetOrientation(orientation); emptyNd->SetDataValid(false); mitk::NavigationData::Pointer tmp; - for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) + + for (unsigned int index = 0; index < this->GetNumberOfRequiredOutputs(); index++) { tmp = mitk::NavigationData::New(); tmp->Graft(emptyNd); - this->SetNthOutput(index, tmp); + this->SetNthOutput(index, tmp.GetPointer()); } // find out _NumberOfSnapshots m_NumberOfSnapshots = 0; TiXmlElement* nextND = m_DataElem->FirstChildElement("NavigationData"); while(nextND) { ++m_NumberOfSnapshots; nextND = nextND->NextSiblingElement("NavigationData"); } // e.g. 12 nd found and 2 tools used => number of snapshots is 12:2=6 m_NumberOfSnapshots = m_NumberOfSnapshots/toolcount; } } void mitk::NavigationDataSequentialPlayer::GoToSnapshot(int i) { if(!m_Repeat && (this->GetNumberOfSnapshots() numOfUpdateCalls = 4 if(m_LastGoTo <= i) numOfUpdateCalls = i - m_LastGoTo; // goto(4), m_LastGoTo=7 => numOfUpdateCalls = 7 else { if(!m_Repeat) { std::stringstream message; message <<"Cannot go back to snapshot " << i << " because the " << this->GetNameOfClass() << " is configured to not repeat the" << " navigation data."; MITK_WARN << message.str(); mitkThrowException(mitk::IGTException) << message.str(); } else { numOfUpdateCalls = (m_NumberOfSnapshots - m_LastGoTo) + i; } } for(int j=0; jUpdate(); m_LastGoTo = i; } void mitk::NavigationDataSequentialPlayer:: SetFileName(const std::string& _FileName) { m_FileName = _FileName; if(!m_Doc->LoadFile(m_FileName)) { this->SetNumberOfOutputs(0); std::ostringstream s; s << "File " << _FileName << " could not be loaded"; mitkThrowException(mitk::IGTIOException)<ReinitXML(); } this->Modified(); } void mitk::NavigationDataSequentialPlayer:: SetXMLString(const std::string& _XMLString) { m_XMLString = _XMLString; if((m_Doc->Parse( m_XMLString.c_str()))== NULL) { this->ReinitXML(); } else { //if the string is not an XML string std::ostringstream s; s << "String" << _XMLString << " is not an XML string"; mitkThrowException(mitk::IGTIOException)<Modified(); } void mitk::NavigationDataSequentialPlayer::GenerateData() { assert(m_DataElem); // very important: go through the tools (there could be more than one) mitk::NavigationData::Pointer tmp; - for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++) + for (unsigned int index = 0; index < this->GetNumberOfIndexedOutputs(); index++) { // go to the first element if(!m_CurrentElem) m_CurrentElem = m_DataElem->FirstChildElement("NavigationData"); // go to the next element else { m_CurrentElem = m_CurrentElem->NextSiblingElement(); } // if repeat is on: go back to the first element (prior calls delivered NULL // elem) if(!m_CurrentElem && m_Repeat) m_CurrentElem = m_DataElem->FirstChildElement("NavigationData"); mitk::NavigationData* output = this->GetOutput(index); tmp = this->ReadVersion1(); if(tmp.IsNotNull()) { output->Graft(tmp); m_StreamValid = true; } else // no valid output { output->SetDataValid(false); m_StreamValid = false; m_ErrorMessage = "Error: Cannot parse input file."; mitkThrowException(mitk::IGTException)<ReadNavigationData(elem); } void mitk::NavigationDataSequentialPlayer::UpdateOutputInformation() { this->Modified(); // make sure that we need to be updated Superclass::UpdateOutputInformation(); } diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataSource.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataSource.cpp index 50e7efdc79..691591cf06 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataSource.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataSource.cpp @@ -1,153 +1,153 @@ /*=================================================================== 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 "mitkNavigationDataSource.h" #include "mitkUIDGenerator.h" //Microservices #include #include #include #include "mitkModuleContext.h" const std::string mitk::NavigationDataSource::US_INTERFACE_NAME = "org.mitk.services.NavigationDataSource"; const std::string mitk::NavigationDataSource::US_PROPKEY_DEVICENAME = US_INTERFACE_NAME + ".devicename"; const std::string mitk::NavigationDataSource::US_PROPKEY_ID = US_INTERFACE_NAME + ".id"; const std::string mitk::NavigationDataSource::US_PROPKEY_ISACTIVE = US_INTERFACE_NAME + ".isActive"; mitk::NavigationDataSource::NavigationDataSource() : itk::ProcessObject(), m_Name("NavigationDataSource (no defined type)") { } mitk::NavigationDataSource::~NavigationDataSource() { } mitk::NavigationData* mitk::NavigationDataSource::GetOutput() { - if (this->GetNumberOfOutputs() < 1) + if (this->GetNumberOfIndexedOutputs() < 1) return NULL; return static_cast(this->ProcessObject::GetPrimaryOutput()); } mitk::NavigationData* mitk::NavigationDataSource::GetOutput(DataObjectPointerArraySizeType idx) { NavigationData* out = dynamic_cast( this->ProcessObject::GetOutput(idx) ); if ( out == NULL && this->ProcessObject::GetOutput(idx) != NULL ) { itkWarningMacro (<< "Unable to convert output number " << idx << " to type " << typeid( NavigationData ).name () ); } return out; } mitk::NavigationData* mitk::NavigationDataSource::GetOutput(const std::string& navDataName) { DataObjectPointerArray outputs = this->GetOutputs(); for (DataObjectPointerArray::iterator it = outputs.begin(); it != outputs.end(); ++it) if (navDataName == (static_cast(it->GetPointer()))->GetName()) return static_cast(it->GetPointer()); return NULL; } itk::ProcessObject::DataObjectPointerArraySizeType mitk::NavigationDataSource::GetOutputIndex( std::string navDataName ) { DataObjectPointerArray outputs = this->GetOutputs(); for (DataObjectPointerArray::size_type i = 0; i < outputs.size(); ++i) if (navDataName == (static_cast(outputs.at(i).GetPointer()))->GetName()) return i; throw std::invalid_argument("output name does not exist"); } void mitk::NavigationDataSource::RegisterAsMicroservice(){ // Get Context mitk::ModuleContext* context = GetModuleContext(); // Define ServiceProps ServiceProperties props; mitk::UIDGenerator uidGen = mitk::UIDGenerator ("org.mitk.services.NavigationDataSource.id_", 16); props[ US_PROPKEY_ID ] = uidGen.GetUID(); props[ US_PROPKEY_DEVICENAME ] = m_Name; m_ServiceRegistration = context->RegisterService(this, props); } void mitk::NavigationDataSource::UnRegisterMicroservice(){ m_ServiceRegistration.Unregister(); m_ServiceRegistration = 0; } std::string mitk::NavigationDataSource::GetMicroserviceID(){ return this->m_ServiceRegistration.GetReference().GetProperty(US_PROPKEY_ID).ToString(); } void mitk::NavigationDataSource::GraftOutput(itk::DataObject *graft) { this->GraftNthOutput(0, graft); } void mitk::NavigationDataSource::GraftNthOutput(unsigned int idx, itk::DataObject *graft) { - if ( idx >= this->GetNumberOfOutputs() ) + if ( idx >= this->GetNumberOfIndexedOutputs() ) { itkExceptionMacro(<<"Requested to graft output " << idx << - " but this filter only has " << this->GetNumberOfOutputs() << " Outputs."); + " but this filter only has " << this->GetNumberOfIndexedOutputs() << " Outputs."); } if ( !graft ) { itkExceptionMacro(<<"Requested to graft output with a NULL pointer object" ); } itk::DataObject* output = this->GetOutput(idx); if ( !output ) { itkExceptionMacro(<<"Requested to graft output that is a NULL pointer" ); } // Call Graft on NavigationData to copy member data output->Graft( graft ); } itk::DataObject::Pointer mitk::NavigationDataSource::MakeOutput ( DataObjectPointerArraySizeType /*idx*/ ) { return mitk::NavigationData::New().GetPointer(); } itk::DataObject::Pointer mitk::NavigationDataSource::MakeOutput( const DataObjectIdentifierType & name ) { itkDebugMacro("MakeOutput(" << name << ")"); if( this->IsIndexedOutputName(name) ) { return this->MakeOutput( this->MakeIndexFromOutputName(name) ); } return static_cast(mitk::NavigationData::New().GetPointer()); } mitk::PropertyList::ConstPointer mitk::NavigationDataSource::GetParameters() const { mitk::PropertyList::Pointer p = mitk::PropertyList::New(); // add properties to p like this: //p->SetProperty("MyFilter_MyParameter", mitk::PropertyDataType::New(m_MyParameter)); return mitk::PropertyList::ConstPointer(p); } diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp index bc074aa8ee..184d68731a 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataToNavigationDataFilter.cpp @@ -1,99 +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. ===================================================================*/ #include "mitkNavigationDataToNavigationDataFilter.h" mitk::NavigationDataToNavigationDataFilter::NavigationDataToNavigationDataFilter() : mitk::NavigationDataSource() { mitk::NavigationData::Pointer output = mitk::NavigationData::New(); this->SetNumberOfRequiredOutputs(1); this->SetNthOutput(0, output.GetPointer()); } mitk::NavigationDataToNavigationDataFilter::~NavigationDataToNavigationDataFilter() { } void mitk::NavigationDataToNavigationDataFilter::SetInput( const NavigationData* nd ) { this->SetInput(0, nd); } void mitk::NavigationDataToNavigationDataFilter::SetInput( unsigned int idx, const NavigationData* nd ) { - if ((nd == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one - this->SetNumberOfInputs(this->GetNumberOfInputs() - 1); + if ( nd == NULL ) // if an input is set to NULL, remove it + this->RemoveInput(idx); else - this->ProcessObject::SetNthInput(idx, const_cast(nd)); // Process object is not const-correct so the const_cast is required here - + this->ProcessObject::SetNthInput(idx, const_cast(nd)); // ProcessObject is not const-correct so a const_cast is required here this->CreateOutputsForAllInputs(); } const mitk::NavigationData* mitk::NavigationDataToNavigationDataFilter::GetInput( void ) const { if (this->GetNumberOfInputs() < 1) return NULL; return static_cast(this->ProcessObject::GetInput(0)); } const mitk::NavigationData* mitk::NavigationDataToNavigationDataFilter::GetInput( unsigned int idx ) const { if (this->GetNumberOfInputs() < 1) return NULL; return static_cast(this->ProcessObject::GetInput(idx)); } const mitk::NavigationData* mitk::NavigationDataToNavigationDataFilter::GetInput(std::string navDataName) const { const DataObjectPointerArray& inputs = const_cast(this)->GetInputs(); for (DataObjectPointerArray::const_iterator it = inputs.begin(); it != inputs.end(); ++it) if (std::string(navDataName) == (static_cast(it->GetPointer()))->GetName()) return static_cast(it->GetPointer()); return NULL; } itk::ProcessObject::DataObjectPointerArraySizeType mitk::NavigationDataToNavigationDataFilter::GetInputIndex( std::string navDataName ) { DataObjectPointerArray outputs = this->GetInputs(); for (DataObjectPointerArray::size_type i = 0; i < outputs.size(); ++i) if (navDataName == (static_cast(outputs.at(i).GetPointer()))->GetName()) return i; throw std::invalid_argument("output name does not exist"); } void mitk::NavigationDataToNavigationDataFilter::CreateOutputsForAllInputs() { this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs()); // create outputs for all inputs for (unsigned int idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx) if (this->GetOutput(idx) == NULL) { mitk::NavigationData::Pointer newOutput = mitk::NavigationData::New(); this->SetNthOutput(idx, newOutput); } this->Modified(); } diff --git a/Modules/IGT/Testing/files.cmake b/Modules/IGT/Testing/files.cmake index ffe9da5304..3d770dcc0f 100644 --- a/Modules/IGT/Testing/files.cmake +++ b/Modules/IGT/Testing/files.cmake @@ -1,49 +1,49 @@ set(MODULE_TESTS mitkCameraVisualizationTest.cpp mitkClaronInterfaceTest.cpp mitkClaronToolTest.cpp mitkClaronTrackingDeviceTest.cpp mitkInternalTrackingToolTest.cpp mitkNavigationDataDisplacementFilterTest.cpp mitkNavigationDataLandmarkTransformFilterTest.cpp mitkNavigationDataObjectVisualizationFilterTest.cpp mitkNavigationDataTest.cpp mitkNavigationDataRecorderTest.cpp mitkNavigationDataReferenceTransformFilterTest.cpp - # mitkNavigationDataSequentialPlayerTest.cpp commented out because of bug 15020 + mitkNavigationDataSequentialPlayerTest.cpp mitkNavigationDataSourceTest.cpp mitkNavigationDataToMessageFilterTest.cpp mitkNavigationDataToNavigationDataFilterTest.cpp mitkNavigationDataToPointSetFilterTest.cpp # mitkNavigationDataTransformFilterTest.cpp commented out because of bug 15023 mitkNDIPassiveToolTest.cpp mitkNDIProtocolTest.cpp mitkNDITrackingDeviceTest.cpp mitkTimeStampTest.cpp mitkTrackingVolumeGeneratorTest.cpp mitkTrackingDeviceTest.cpp mitkTrackingToolTest.cpp mitkVirtualTrackingDeviceTest.cpp mitkNavigationDataPlayerTest.cpp # see bug 11636 (extend this test by microservices) mitkTrackingDeviceSourceTest.cpp mitkTrackingDeviceSourceConfiguratorTest.cpp mitkNavigationDataEvaluationFilterTest.cpp mitkTrackingTypesTest.cpp # ------------------ Navigation Tool Management Tests ------------------- mitkNavigationToolStorageTest.cpp mitkNavigationToolStorageSerializerAndDeserializerTest.cpp mitkNavigationToolTest.cpp mitkNavigationToolReaderAndWriterTest.cpp # ----------------------------------------------------------------------- # ------------------ Deavtivated Tests ---------------------------------- # ----------------------------------------------------------------------- ) set(MODULE_CUSTOM_TESTS mitkNDIAuroraHardwareTest.cpp mitkNDIPolarisHardwareTest.cpp mitkClaronTrackingDeviceHardwareTest.cpp ) diff --git a/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp b/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp index c3a3d7e03f..b92650d64a 100644 --- a/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataSequentialPlayerTest.cpp @@ -1,223 +1,224 @@ /*=================================================================== 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 "mitkTestingMacros.h" #include #include //foe exceptions #include "mitkIGTException.h" #include "mitkIGTIOException.h" const char* XML_STRING = "" "" "" "" "" "" "" ""; const char* XML_INVALID_TESTSTRING = "< ToolCount=\"2\">" "" "" "" "" "" "" ""; vnl_vector tTool0Snapshot1(3); vnl_vector tTool1Snapshot2(3); mitk::Quaternion qTool0Snapshot0; mitk::Quaternion qTool1Snapshot1; mitk::NavigationDataSequentialPlayer::Pointer player( mitk::NavigationDataSequentialPlayer::New()); bool runLoop() { bool success = true; mitk::NavigationData::Pointer nd0; mitk::NavigationData::Pointer nd1; for(unsigned int i=0; iGetNumberOfSnapshots();++i) { player->Update(); nd0 = player->GetOutput(); nd1 = player->GetOutput(1); // test some values if(nd0.IsNull() || nd1.IsNull()) return false; if(i==0) { if (!(qTool0Snapshot0.as_vector() == nd0->GetOrientation().as_vector())) {success = false;} } else if(i==1) { if (!(tTool0Snapshot1 == nd0->GetPosition().GetVnlVector())) {success = false;} else if (!(qTool1Snapshot1.as_vector() == nd1->GetOrientation().as_vector())) {success = false;} } else if(i==2) // should be repeated { if (!(tTool1Snapshot2 == nd1->GetPosition().GetVnlVector())) {success = false;} } } return success; } void TestStandardWorkflow() { // create test values valid for the xml data above tTool0Snapshot1[0] = -336.65; tTool0Snapshot1[1] = 138.5; tTool0Snapshot1[2]= -2061.07; tTool1Snapshot2[0] = -56.93; tTool1Snapshot2[1] = 233.79; tTool1Snapshot2[2]= -2042.6; vnl_vector_fixed qVec; qVec[0] = 0.0085; qVec[1] = -0.0576; qVec[2]= -0.0022; qVec[3]= 0.9982; qTool0Snapshot0 = mitk::Quaternion(qVec); qVec[0] = 0.4683; qVec[1] = 0.0188; qVec[2]= -0.8805; qVec[3]= 0.0696; qTool1Snapshot1 = mitk::Quaternion(qVec); //test SetXMLString() player->SetXMLString(XML_STRING); MITK_TEST_CONDITION_REQUIRED(player->GetNumberOfSnapshots() == 3,"Testing method SetXMLString with 3 navigation datas."); + MITK_TEST_CONDITION_REQUIRED(player->GetNumberOfIndexedOutputs() == 2,"Testing number of outputs"); //rest repeat player->SetRepeat(true); MITK_TEST_CONDITION_REQUIRED(runLoop(),"Testing first run."); MITK_TEST_CONDITION_REQUIRED(runLoop(),"Testing second run."); //repeat is on should work a second time // now test the go to snapshot function player->GoToSnapshot(3); mitk::NavigationData::Pointer nd1 = player->GetOutput(1); MITK_TEST_CONDITION(tTool1Snapshot2 == nd1->GetPosition().GetVnlVector(), "Testing GoToSnapshot() [1]"); player->GoToSnapshot(1); mitk::NavigationData::Pointer nd0 = player->GetOutput(); MITK_TEST_CONDITION(qTool0Snapshot0.as_vector() == nd0->GetOrientation().as_vector(), "Testing GoToSnapshot() [2]"); player->GoToSnapshot(3); // and a third time MITK_TEST_CONDITION_REQUIRED(runLoop(),"Tested if repeat works again."); } void TestSetFileNameException() { //testing exception if file name hasnt been set mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer = mitk::NavigationDataSequentialPlayer::New(); bool exceptionThrown=false; try { myTestPlayer->SetFileName(""); } catch(mitk::IGTIOException) { exceptionThrown=true; MITK_TEST_OUTPUT(<<"Tested exception for the case when file version is wrong in SetFileName. Application should not crash."); } MITK_TEST_CONDITION_REQUIRED(exceptionThrown, "Testing SetFileName method if exception (if file name hasnt been set) was thrown."); //testing ReInItXML method if data element is not found mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer1 = mitk::NavigationDataSequentialPlayer::New(); std::string file = mitk::StandardFileLocations::GetInstance()->FindFile("NavigationDataTestDataInvalidTags.xml", "Modules/IGT/Testing/Data"); bool exceptionThrown1=false; try { myTestPlayer1->SetFileName(file); } catch(mitk::IGTException) { exceptionThrown1=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown1, "Testing SetFileName method if exception (if data element not found) was thrown."); } void TestGoToSnapshotException() { //testing GoToSnapShot for exception mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer2 = mitk::NavigationDataSequentialPlayer::New(); myTestPlayer2->SetXMLString(XML_STRING); bool exceptionThrown2=false; try { myTestPlayer2->GoToSnapshot(1000); } catch(mitk::IGTException) { exceptionThrown2=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown2, "Testing if exception is thrown when GoToSnapShot method is called with an index that doesn't exist."); } void TestSetXMLStringException() { mitk::NavigationDataSequentialPlayer::Pointer myTestPlayer3 = mitk::NavigationDataSequentialPlayer::New(); bool exceptionThrown3=false; //The string above XML_INVALID_TESTSTRING is a wrong string, some element were deleted in above try { myTestPlayer3->SetXMLString(XML_INVALID_TESTSTRING); } catch(mitk::IGTException) { exceptionThrown3=true; } MITK_TEST_CONDITION_REQUIRED(exceptionThrown3, "Testing SetXMLString method with an invalid XML string."); } /**Documentation * test for the class "NavigationDataRecorder". */ int mitkNavigationDataSequentialPlayerTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationDataSequentialPlayer"); TestStandardWorkflow(); TestSetFileNameException(); TestSetXMLStringException(); TestGoToSnapshotException(); MITK_TEST_END(); } diff --git a/Modules/IGT/Testing/mitkNavigationDataToNavigationDataFilterTest.cpp b/Modules/IGT/Testing/mitkNavigationDataToNavigationDataFilterTest.cpp index ef731debbf..4984da843e 100644 --- a/Modules/IGT/Testing/mitkNavigationDataToNavigationDataFilterTest.cpp +++ b/Modules/IGT/Testing/mitkNavigationDataToNavigationDataFilterTest.cpp @@ -1,109 +1,107 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkNavigationDataToNavigationDataFilter.h" #include "mitkNavigationData.h" #include "mitkTestingMacros.h" /**Documentation * \brief test class to be able to instantiate the normally abstract (private constructor) mitk::NavigationDataToNavigationDataFilter */ class NavigationDataToNavigationDataFilterTestClass : public mitk::NavigationDataToNavigationDataFilter { public: mitkClassMacro(NavigationDataToNavigationDataFilterTestClass, NavigationDataToNavigationDataFilter); itkNewMacro(Self); }; /**Documentation * test for the class "NavigationDataToNavigationDataFilter". */ int mitkNavigationDataToNavigationDataFilterTest(int /* argc */, char* /*argv*/[]) { MITK_TEST_BEGIN("NavigationDataToNavigationDataFilter") // let's create an object of our class mitk::NavigationDataToNavigationDataFilter::Pointer myFilter = NavigationDataToNavigationDataFilterTestClass::New().GetPointer(); // create testing subclass, but treat it like the real NavigationDataToNavigationDataFilter MITK_TEST_CONDITION_REQUIRED(myFilter.IsNotNull(),"Testing instantiation"); /* create helper objects: navigation data with position as origin, zero quaternion, zero error and data valid */ mitk::NavigationData::PositionType initialPos; mitk::FillVector3D(initialPos, 1.0, 2.0, 3.0); mitk::NavigationData::OrientationType initialOri(0.1, 0.2, 0.3, 0.4); mitk::ScalarType initialError(22.22); bool initialValid(true); mitk::NavigationData::Pointer nd0 = mitk::NavigationData::New(); nd0->SetPosition(initialPos); nd0->SetOrientation(initialOri); nd0->SetPositionAccuracy(initialError); nd0->SetDataValid(initialValid); nd0->SetName("testName"); MITK_TEST_CONDITION(myFilter->GetOutput() != NULL, "testing GetOutput()"); MITK_TEST_CONDITION(myFilter->GetInput() == NULL, "testing GetInput() without SetInput()"); MITK_TEST_CONDITION(myFilter->GetInput(0) == NULL, "testing GetInput(0) without SetInput()"); myFilter->SetInput(nd0); MITK_TEST_CONDITION(myFilter->GetInput() == nd0, "testing Set-/GetInput()"); MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0)"); MITK_TEST_CONDITION(myFilter->GetOutput() != NULL, "testing GetOutput() after SetInput()"); MITK_TEST_CONDITION(myFilter->GetOutput() != NULL, "testing GetOutput() after SetInput()"); MITK_TEST_CONDITION(myFilter->GetOutput() != nd0, "testing GetOutput() different object than input"); // check getInput() string input MITK_TEST_CONDITION(myFilter->GetInput("invalidName") == NULL, "testing GetInput(string) invalid string"); MITK_TEST_CONDITION(myFilter->GetInput("testName") == nd0, "testing GetInput(string) valid string"); // check getInputIndex() string input bool throwsException = false; try { myFilter->GetInputIndex("invalidName"); } catch(std::invalid_argument e) { throwsException = true; } MITK_TEST_CONDITION_REQUIRED(throwsException, "testing GetInputIndex(string) invalid string"); MITK_TEST_CONDITION(myFilter->GetInputIndex("testName") == 0, "testing GetInputIndex(string) valid string"); mitk::NavigationData::Pointer nd1 = mitk::NavigationData::New(); nd1->Graft(nd0); nd1->SetDataValid(false); myFilter->SetInput(1, nd1); MITK_TEST_CONDITION(myFilter->GetInput(1) == nd1, "testing Set-/GetInput(1)"); MITK_TEST_CONDITION(myFilter->GetInput(0) == nd0, "testing Set-/GetInput(0) again"); MITK_TEST_CONDITION(myFilter->GetOutput(1) != NULL, "testing GetOutput() after SetInput()"); MITK_TEST_CONDITION(myFilter->GetOutput() != myFilter->GetOutput(1), "testing GetOutput() different object than GetOutput(1)"); myFilter->SetInput(10, nd1); MITK_TEST_CONDITION(myFilter->GetNumberOfIndexedInputs() == 11, "testing SetInput(10) produces 11 outputs"); MITK_TEST_CONDITION(myFilter->GetInput(10) == nd1, "testing Set-/GetInput(10)"); - /* COMMENTED OUT BECAUSE OF BUG 15017! - myFilter->SetInput(10, NULL); //this doesn't remove the output any more in ITK4 + myFilter->SetInput(10, NULL); MITK_TEST_CONDITION(myFilter->GetNumberOfIndexedInputs() == 10, "testing SetInput(10, NULL) removes output with index 10"); myFilter->SetInput(1, NULL); MITK_TEST_CONDITION(myFilter->GetNumberOfIndexedInputs() == 10, "testing SetInput(1, NULL) does not change number of outputs"); - */ // always end with this! MITK_TEST_END(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp index a7244d5578..5683c2355d 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp @@ -1,815 +1,826 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkIVIMView.h" #include "QmitkStdMultiWidget.h" // qt #include "qmessagebox.h" #include "qclipboard.h" // mitk #include "mitkDiffusionImage.h" #include "mitkImageCast.h" // itk #include "itkScalarImageToHistogramGenerator.h" #include "itkRegionOfInterestImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" // itk/mitk #include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h" #include "itkRegularizedIVIMReconstructionFilter.h" #include "mitkImageCast.h" const std::string QmitkIVIMView::VIEW_ID = "org.mitk.views.ivim"; QmitkIVIMView::QmitkIVIMView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) - , m_Active(false) , m_SliceObserverTag1(0), m_SliceObserverTag2(0), m_SliceObserverTag3(0) , m_DiffusionImageNode(NULL) , m_MaskImageNode(NULL) + , m_Active(false) { } QmitkIVIMView::~QmitkIVIMView() { // QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false); // if(MultiWidget) // { // //unregister observers when view is destroyed // if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag1 ); // } // if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag2 ); // } // if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0) // { // mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController(); // slicer->RemoveObserver( m_SliceObserverTag3 ); // } // } } void QmitkIVIMView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkIVIMViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_ButtonStart, SIGNAL(clicked()), this, SLOT(FittIVIMStart()) ); connect( m_Controls->m_ButtonAutoThres, SIGNAL(clicked()), this, SLOT(AutoThreshold()) ); connect( m_Controls->m_MethodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(MethodCombo(int)) ); connect( m_Controls->m_DStarSlider, SIGNAL(valueChanged(int)), this, SLOT(DStarSlider(int)) ); connect( m_Controls->m_BThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(BThreshSlider(int)) ); connect( m_Controls->m_S0ThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(S0ThreshSlider(int)) ); connect( m_Controls->m_NumItSlider, SIGNAL(valueChanged(int)), this, SLOT(NumItsSlider(int)) ); connect( m_Controls->m_LambdaSlider, SIGNAL(valueChanged(int)), this, SLOT(LambdaSlider(int)) ); connect( m_Controls->m_CheckDStar, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_CheckD, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_Checkf, SIGNAL(clicked()), this, SLOT(Checkbox()) ); connect( m_Controls->m_ChooseMethod, SIGNAL(clicked()), this, SLOT(ChooseMethod()) ); connect( m_Controls->m_CurveClipboard, SIGNAL(clicked()), this, SLOT(ClipboardCurveButtonClicked()) ); connect( m_Controls->m_ValuesClipboard, SIGNAL(clicked()), this, SLOT(ClipboardStatisticsButtonClicked()) ); } QString dstar = QString::number(m_Controls->m_DStarSlider->value()/1000.0); m_Controls->m_DStarLabel->setText(dstar); QString bthresh = QString::number(m_Controls->m_BThreshSlider->value()*5.0); m_Controls->m_BThreshLabel->setText(bthresh); QString s0thresh = QString::number(m_Controls->m_S0ThreshSlider->value()*0.5); m_Controls->m_S0ThreshLabel->setText(s0thresh); QString numits = QString::number(m_Controls->m_NumItSlider->value()); m_Controls->m_NumItsLabel->setText(numits); QString lambda = QString::number(m_Controls->m_LambdaSlider->value()*.00001); m_Controls->m_LambdaLabel->setText(lambda); m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); m_Controls->m_Warning->setVisible(false); MethodCombo(m_Controls->m_MethodCombo->currentIndex()); } void QmitkIVIMView::Checkbox() { itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::MethodCombo(int val) { switch(val) { case 0: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 1: m_Controls->m_DstarFrame->setVisible(true); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 2: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 3: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(true); m_Controls->m_NeglBframe->setVisible(true); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; case 4: m_Controls->m_DstarFrame->setVisible(false); m_Controls->m_NeglSiFrame->setVisible(false); m_Controls->m_NeglBframe->setVisible(false); m_Controls->m_IterationsFrame->setVisible(false); m_Controls->m_LambdaFrame->setVisible(false); break; } itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::DStarSlider (int val) { QString sval = QString::number(val/1000.0); m_Controls->m_DStarLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::BThreshSlider (int val) { QString sval = QString::number(val*5.0); m_Controls->m_BThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::S0ThreshSlider (int val) { QString sval = QString::number(val*0.5); m_Controls->m_S0ThreshLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::NumItsSlider (int val) { QString sval = QString::number(val); m_Controls->m_NumItsLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::LambdaSlider (int val) { QString sval = QString::number(val*.00001); m_Controls->m_LambdaLabel->setText(sval); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command ); } } void QmitkIVIMView::StdMultiWidgetNotAvailable() { { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag1 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag2 ); } { mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController(); slicer->RemoveObserver( m_SliceObserverTag3 ); } m_MultiWidget = NULL; } void QmitkIVIMView::OnSelectionChanged( std::vector nodes ) { bool foundOneDiffusionImage = false; m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_MaskImageLabel->setText("optional"); m_MaskImageNode = NULL; m_DiffusionImageNode = NULL; // iterate all selected objects, adjust warning visibility for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast*>(node->GetData()) ) { m_DiffusionImageNode = node; foundOneDiffusionImage = true; m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_MaskImageNode = node; m_Controls->m_MaskImageLabel->setText(node->GetName().c_str()); } } } } if (m_DiffusionImageNode.IsNotNull()) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_InputData->setTitle("Input Data"); } else + { m_Controls->m_VisualizeResultsWidget->setVisible(false); + m_Controls->m_DiffusionImageLabel->setText("mandatory"); + } m_Controls->m_ButtonStart->setEnabled( foundOneDiffusionImage ); m_Controls->m_ButtonAutoThres->setEnabled( foundOneDiffusionImage ); m_Controls->m_ControlsFrame->setEnabled( foundOneDiffusionImage ); m_Controls->m_BottomControlsFrame->setEnabled( foundOneDiffusionImage ); itk::StartEvent dummy; OnSliceChanged(dummy); } void QmitkIVIMView::AutoThreshold() { std::vector nodes = this->GetDataManagerSelection(); if (nodes.empty()) return; if (!nodes.front()) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing."); return; } typedef mitk::DiffusionImage DiffImgType; DiffImgType* dimg = dynamic_cast(nodes.front()->GetData()); if (!dimg) { // Nothing selected. Inform the user and return QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } // find bzero index int index = -1; DiffImgType::GradientDirectionContainerType::Pointer directions = dimg->GetDirections(); for(DiffImgType::GradientDirectionContainerType::ConstIterator it = directions->Begin(); it != directions->End(); ++it) { index++; DiffImgType::GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = dimg->GetVectorImage(); int vecLength = vecimg->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; MITK_INFO << "Performing Histogram Analysis on Channel" << index; typedef itk::Image ImgType; ImgType::Pointer img = ImgType::New(); mitk::CastToItkImage(dimg, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); - itw = itw.Begin(); + itw.GoToBegin(); itk::ImageRegionConstIterator itr (vecimg, vecimg->GetLargestPossibleRegion() ); - itr = itr.Begin(); + itr.GoToBegin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } typedef itk::Statistics::ScalarImageToHistogramGenerator< ImgType > HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New(); histogramGenerator->SetInput( img ); histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram histogramGenerator->SetNumberOfBins( 100 ); // CT range [-1024, +2048] --> bin size 4 values histogramGenerator->SetHistogramMin( dimg->GetScalarValueMin() ); histogramGenerator->SetHistogramMax( dimg->GetScalarValueMax() * .5 ); histogramGenerator->Compute(); HistogramType::ConstIterator iter = histogramGenerator->GetOutput()->Begin(); float maxFreq = 0; float maxValue = 0; while ( iter != histogramGenerator->GetOutput()->End() ) { if(iter.GetFrequency() > maxFreq) { maxFreq = iter.GetFrequency(); maxValue = iter.GetMeasurementVector()[0]; } ++iter; } maxValue *= 2; int sliderPos = maxValue * 2; m_Controls->m_S0ThreshSlider->setValue(sliderPos); S0ThreshSlider(sliderPos); } void QmitkIVIMView::FittIVIMStart() { std::vector nodes = this->GetDataManagerSelection(); mitk::DiffusionImage* img = 0; - for ( int i=0; i*>(nodes.at(i)->GetData()); if (img) break; } if (!img) { QMessageBox::information( NULL, "Template", "No valid diffusion image was found."); return; } typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = img->GetVectorImage(); OutImgType::IndexType dummy; FittIVIM(vecimg, img->GetDirections(), img->GetB_Value(), true, dummy); OutputToDatastorage(nodes); } void QmitkIVIMView::OnSliceChanged(const itk::EventObject& /*e*/) { if(!m_Visible) return; m_Controls->m_Warning->setVisible(false); if(!m_Controls || m_DiffusionImageNode.IsNull()) return; m_Controls->m_VisualizeResultsWidget->setVisible(false); mitk::DiffusionImage::Pointer diffusionImg = dynamic_cast*>(m_DiffusionImageNode->GetData()); mitk::Image::Pointer maskImg = NULL; if (m_MaskImageNode.IsNotNull()) maskImg = dynamic_cast(m_MaskImageNode->GetData()); if (!m_MultiWidget) return; typedef itk::VectorImage VecImgType; VecImgType::Pointer vecimg = (VecImgType*)diffusionImg->GetVectorImage().GetPointer(); VecImgType::Pointer roiImage = VecImgType::New(); bool success = false; if(maskImg.IsNull()) { int roisize = 0; if(m_Controls->m_MethodCombo->currentIndex() == 4) roisize = 5; mitk::Point3D pos = m_MultiWidget->GetCrossPosition(); VecImgType::IndexType crosspos; diffusionImg->GetTimeSlicedGeometry()->WorldToIndex(pos, crosspos); if (!vecimg->GetLargestPossibleRegion().IsInside(crosspos)) { m_Controls->m_Warning->setText(QString("Crosshair position not inside of selected diffusion weighted image. Reinit needed!")); m_Controls->m_Warning->setVisible(true); return; } else m_Controls->m_Warning->setVisible(false); VecImgType::IndexType index; index[0] = crosspos[0] - roisize; index[0] = index[0] < 0 ? 0 : index[0]; index[1] = crosspos[1] - roisize; index[1] = index[1] < 0 ? 0 : index[1]; index[2] = crosspos[2] - roisize; index[2] = index[2] < 0 ? 0 : index[2]; VecImgType::SizeType size; size[0] = roisize*2+1; size[1] = roisize*2+1; size[2] = roisize*2+1; VecImgType::SizeType maxSize = vecimg->GetLargestPossibleRegion().GetSize(); size[0] = index[0]+size[0] > maxSize[0] ? maxSize[0]-index[0] : size[0]; size[1] = index[1]+size[1] > maxSize[1] ? maxSize[1]-index[1] : size[1]; size[2] = index[2]+size[2] > maxSize[2] ? maxSize[2]-index[2] : size[2]; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); VecImgType::IndexType newstart; newstart.Fill(0); VecImgType::RegionType newregion; newregion.SetSize( size ); newregion.SetIndex( newstart ); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( newregion ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(newstart, vecimg->GetPixel(index)); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, crosspos); } else { typedef itk::Image MaskImgType; MaskImgType::Pointer maskItk; CastToItkImage( maskImg, maskItk ); mitk::Point3D pos; pos[0] = 0; pos[1] = 0; pos[2] = 0; VecImgType::IndexType index; index[0] = 0; index[1] = 0; index[2] = 0; VecImgType::SizeType size; size[0] = 1; size[1] = 1; size[2] = 1; VecImgType::RegionType region; region.SetSize( size ); region.SetIndex( index ); vecimg->SetRequestedRegion( region ); // iterators over output and input itk::ImageRegionConstIteratorWithIndex vecit(vecimg, vecimg->GetLargestPossibleRegion()); itk::VariableLengthVector avg(vecimg->GetVectorLength()); avg.Fill(0); float numPixels = 0; while ( ! vecit.IsAtEnd() ) { VecImgType::PointType point; vecimg->TransformIndexToPhysicalPoint(vecit.GetIndex(), point); MaskImgType::IndexType index; maskItk->TransformPhysicalPointToIndex(point, index); if(maskItk->GetPixel(index) != 0) { avg += vecit.Get(); numPixels += 1.0; } // update iterators ++vecit; } avg /= numPixels; m_Controls->m_Warning->setText(QString("Averaging ")+QString::number((int)numPixels)+QString(" voxels!")); m_Controls->m_Warning->setVisible(true); roiImage->CopyInformation( vecimg ); roiImage->SetRegions( region ); roiImage->SetOrigin( pos ); roiImage->Allocate(); roiImage->SetPixel(index, avg); success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetB_Value(), false, index); } vecimg->SetRegions( vecimg->GetLargestPossibleRegion() ); if (success) { m_Controls->m_VisualizeResultsWidget->setVisible(true); m_Controls->m_VisualizeResultsWidget->SetParameters(m_Snap); } } bool QmitkIVIMView::FittIVIM(itk::VectorImage* vecimg, DirContainerType* dirs, float bval, bool multivoxel, OutImgType::IndexType &crosspos) { IVIMFilterType::Pointer filter = IVIMFilterType::New(); filter->SetInput(vecimg); filter->SetGradientDirections(dirs); filter->SetBValue(bval); switch(m_Controls->m_MethodCombo->currentIndex()) { case 0: filter->SetMethod(IVIMFilterType::IVIM_FIT_ALL); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 1: filter->SetMethod(IVIMFilterType::IVIM_DSTAR_FIX); filter->SetDStar(m_Controls->m_DStarLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); break; case 2: filter->SetMethod(IVIMFilterType::IVIM_D_THEN_DSTAR); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 3: filter->SetMethod(IVIMFilterType::IVIM_LINEAR_D_THEN_F); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; case 4: filter->SetMethod(IVIMFilterType::IVIM_REGULARIZED); filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble()); filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble()); filter->SetNumberIterations(m_Controls->m_NumItsLabel->text().toInt()); filter->SetLambda(m_Controls->m_LambdaLabel->text().toDouble()); filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked()); break; } if(!multivoxel) { filter->SetFitDStar(true); } filter->SetNumberOfThreads(1); filter->SetVerbose(false); filter->SetCrossPosition(crosspos); try{ filter->Update(); m_Snap = filter->GetSnapshot(); m_DStarMap = filter->GetOutput(2); m_DMap = filter->GetOutput(1); m_fMap = filter->GetOutput(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; m_Controls->m_Warning->setText(QString("IVIM fit not possible: ")+ex.GetDescription()); m_Controls->m_Warning->setVisible(true); return false; } return true; } void QmitkIVIMView::OutputToDatastorage(std::vector nodes) { // Outputs to Datastorage QString basename(nodes.front()->GetName().c_str()); if(m_Controls->m_CheckDStar->isChecked()) { mitk::Image::Pointer dstarimage = mitk::Image::New(); dstarimage->InitializeByItk(m_DStarMap.GetPointer()); dstarimage->SetVolume(m_DStarMap->GetBufferPointer()); QString newname2 = basename; newname2 = newname2.append("_DStarMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node2=mitk::DataNode::New(); node2->SetData( dstarimage ); node2->SetName(newname2.toAscii()); GetDefaultDataStorage()->Add(node2); } if(m_Controls->m_CheckD->isChecked()) { mitk::Image::Pointer dimage = mitk::Image::New(); dimage->InitializeByItk(m_DMap.GetPointer()); dimage->SetVolume(m_DMap->GetBufferPointer()); QString newname1 = basename; newname1 = newname1.append("_DMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node1=mitk::DataNode::New(); node1->SetData( dimage ); node1->SetName(newname1.toAscii()); GetDefaultDataStorage()->Add(node1); } if(m_Controls->m_Checkf->isChecked()) { mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk(m_fMap.GetPointer()); image->SetVolume(m_fMap->GetBufferPointer()); QString newname0 = basename; newname0 = newname0.append("_fMap_%1").arg(m_Controls->m_MethodCombo->currentText()); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); node->SetName(newname0.toAscii()); GetDefaultDataStorage()->Add(node); } m_MultiWidget->RequestUpdate(); + // reset the data node labels, the selection in DataManager is lost after adding + // a new node -> we cannot directly proceed twice, the DWI ( and MASK) image have to be selected again + m_Controls->m_InputData->setTitle("Please Select Input Data"); + m_Controls->m_DiffusionImageLabel->setText("mandatory"); + m_Controls->m_MaskImageLabel->setText("optional"); + m_MaskImageNode = NULL; + m_DiffusionImageNode = NULL; + } void QmitkIVIMView::ChooseMethod() { m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked()); } void QmitkIVIMView::ClipboardCurveButtonClicked() { if(true) { QString clipboard("Measurement Points\n"); - for ( int i=0; isetText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::ClipboardStatisticsButtonClicked() { if ( true ) { QString clipboard( "f \t D \t D* \n" ); clipboard = clipboard.append( "%L1 \t %L2 \t %L3" ) .arg( m_Snap.currentF, 0, 'f', 10 ) .arg( m_Snap.currentD, 0, 'f', 10 ) .arg( m_Snap.currentDStar, 0, 'f', 10 ) ; QApplication::clipboard()->setText( clipboard, QClipboard::Clipboard ); } else { QApplication::clipboard()->clear(); } } void QmitkIVIMView::Activated() { m_Active = true; } void QmitkIVIMView::Deactivated() { m_Active = false; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp index 1ec19523bc..65e522a80e 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStochasticFiberTrackingView.cpp @@ -1,289 +1,289 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include #include // Qmitk #include "QmitkStochasticFiberTrackingView.h" #include "QmitkStdMultiWidget.h" // Qt #include // MITK #include #include // VTK #include #include #include #include #include #include const std::string QmitkStochasticFiberTrackingView::VIEW_ID = "org.mitk.views.stochasticfibertracking"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkStochasticFiberTrackingView::QmitkStochasticFiberTrackingView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_SeedRoi( NULL ) , m_DiffusionImage( NULL ) { } // Destructor QmitkStochasticFiberTrackingView::~QmitkStochasticFiberTrackingView() { } void QmitkStochasticFiberTrackingView::CreateQtPartControl( QWidget *parent ) { if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkStochasticFiberTrackingViewControls; m_Controls->setupUi( parent ); connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) ); connect( m_Controls->m_SeedsPerVoxelSlider, SIGNAL(valueChanged(int)), this, SLOT(OnSeedsPerVoxelChanged(int)) ); connect( m_Controls->m_MaxCacheSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnMaxCacheSizeChanged(int)) ); connect( m_Controls->m_MaxTractLengthSlider, SIGNAL(valueChanged(int)), this, SLOT(OnMaxTractLengthChanged(int)) ); } } void QmitkStochasticFiberTrackingView::OnSeedsPerVoxelChanged(int value) { m_Controls->m_SeedsPerVoxelLabel->setText(QString("Seeds per Voxel: ")+QString::number(value)); } void QmitkStochasticFiberTrackingView::OnMaxTractLengthChanged(int value) { m_Controls->m_MaxTractLengthLabel->setText(QString("Max. Tract Length: ")+QString::number(value)); } void QmitkStochasticFiberTrackingView::OnMaxCacheSizeChanged(int value) { m_Controls->m_MaxCacheSizeLabel->setText(QString("Max. Cache Size: ")+QString::number(value)+"GB"); } void QmitkStochasticFiberTrackingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkStochasticFiberTrackingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkStochasticFiberTrackingView::OnSelectionChanged( std::vector nodes ) { m_DiffusionImageNode = NULL; m_DiffusionImage = NULL; m_SeedRoi = NULL; m_Controls->m_DiffusionImageLabel->setText("mandatory"); m_Controls->m_RoiImageLabel->setText("mandatory"); for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast*>(node->GetData()) ) { m_DiffusionImageNode = node; m_DiffusionImage = dynamic_cast*>(node->GetData()); m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_SeedRoi = dynamic_cast(node->GetData()); m_Controls->m_RoiImageLabel->setText(node->GetName().c_str()); } } } } if(m_DiffusionImage.IsNotNull() && m_SeedRoi.IsNotNull()) { m_Controls->m_InputData->setTitle("Input Data"); m_Controls->commandLinkButton->setEnabled(true); } else { m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->commandLinkButton->setEnabled(false); } } void QmitkStochasticFiberTrackingView::DoFiberTracking() { typedef itk::VectorImage< short int, 3 > DWIVectorImageType; typedef itk::Image< float, 3 > FloatImageType; typedef itk::Image< unsigned int, 3 > CImageType; typedef itk::StochasticTractographyFilter< DWIVectorImageType, FloatImageType, CImageType > TrackingFilterType; typedef itk::DTITubeSpatialObject<3> DTITubeType; typedef itk::DTITubeSpatialObjectPoint<3> DTITubePointType; typedef itk::SceneSpatialObject<3> SceneSpatialObjectType; /* get Gradients/Direction of dwi */ itk::VectorContainer< unsigned int, vnl_vector_fixed >::Pointer Pdir = m_DiffusionImage->GetDirections(); /* bValueContainer, Container includes b-values according to corresponding gradient-direction*/ TrackingFilterType::bValueContainerType::Pointer vecCont = TrackingFilterType::bValueContainerType::New(); /* for each gradient set b-Value; for 0-gradient set b-value eq. 0 */ for ( int i=0; i<(int)Pdir->size(); ++i) { vnl_vector_fixed valsGrad = Pdir->at(i); if (valsGrad.get(0) == 0 && valsGrad.get(1) == 0 && valsGrad.get(2) == 0) { //set 0-Gradient to bValue 0 vecCont->InsertElement(i,0); }else{ vecCont->InsertElement(i,m_DiffusionImage->GetB_Value()); } } /* define measurement frame (identity-matrix 3x3) */ TrackingFilterType::MeasurementFrameType measurement_frame = m_DiffusionImage->GetMeasurementFrame(); /* generate white matterImage (dummy?)*/ FloatImageType::Pointer wmImage = FloatImageType::New(); wmImage->SetSpacing( m_DiffusionImage->GetVectorImage()->GetSpacing() ); wmImage->SetOrigin( m_DiffusionImage->GetVectorImage()->GetOrigin() ); wmImage->SetDirection( m_DiffusionImage->GetVectorImage()->GetDirection() ); wmImage->SetLargestPossibleRegion( m_DiffusionImage->GetVectorImage()->GetLargestPossibleRegion() ); wmImage->SetBufferedRegion( wmImage->GetLargestPossibleRegion() ); wmImage->SetRequestedRegion( wmImage->GetLargestPossibleRegion() ); wmImage->Allocate(); itk::ImageRegionIterator ot(wmImage, wmImage->GetLargestPossibleRegion() ); while (!ot.IsAtEnd()) { ot.Set(1); ++ot; } /* init TractographyFilter */ TrackingFilterType::Pointer trackingFilter = TrackingFilterType::New(); - trackingFilter->SetInput(m_DiffusionImage->GetVectorImage().GetPointer()); + trackingFilter->SetPrimaryInput(m_DiffusionImage->GetVectorImage().GetPointer()); trackingFilter->SetbValues(vecCont); trackingFilter->SetGradients(Pdir); trackingFilter->SetMeasurementFrame(measurement_frame); trackingFilter->SetWhiteMatterProbabilityImage(wmImage); trackingFilter->SetTotalTracts(m_Controls->m_SeedsPerVoxelSlider->value()); trackingFilter->SetMaxLikelihoodCacheSize(m_Controls->m_MaxCacheSizeSlider->value()*1000); trackingFilter->SetMaxTractLength(m_Controls->m_MaxTractLengthSlider->value()); //itk::Image< char, 3 > mitk::ImageToItk< itk::Image< unsigned char, 3 > >::Pointer binaryImageToItk1 = mitk::ImageToItk< itk::Image< unsigned char, 3 > >::New(); binaryImageToItk1->SetInput( m_SeedRoi ); binaryImageToItk1->Update(); vtkSmartPointer vPoints = vtkSmartPointer::New(); vtkSmartPointer vCellArray = vtkSmartPointer::New(); itk::ImageRegionConstIterator< BinaryImageType > it(binaryImageToItk1->GetOutput(), binaryImageToItk1->GetOutput()->GetRequestedRegion()); it.GoToBegin(); mitk::Geometry3D* geom = m_DiffusionImage->GetGeometry(); while(!it.IsAtEnd()) { itk::ImageConstIterator::PixelType tmpPxValue = it.Get(); if(tmpPxValue != 0){ mitk::Point3D point; itk::ImageRegionConstIterator< BinaryImageType >::IndexType seedIdx = it.GetIndex(); trackingFilter->SetSeedIndex(seedIdx); trackingFilter->Update(); /* get results from Filter */ /* write each single tract into member container */ TrackingFilterType::TractContainerType::Pointer container_tmp = trackingFilter->GetOutputTractContainer(); TrackingFilterType::TractContainerType::Iterator elIt = container_tmp->Begin(); TrackingFilterType::TractContainerType::Iterator end = container_tmp->End(); bool addTract = true; while( elIt != end ){ TrackingFilterType::TractContainerType::Element tract = elIt.Value(); TrackingFilterType::TractContainerType::Element::ObjectType::VertexListType::ConstPointer vertexlist = tract->GetVertexList(); vtkSmartPointer vPolyLine = vtkSmartPointer::New(); for( int j=0; j<(int)vertexlist->Size(); j++) { TrackingFilterType::TractContainerType::Element::ObjectType::VertexListType::Element vertex = vertexlist->GetElement(j); mitk::Point3D index; index[0] = (float)vertex[0]; index[1] = (float)vertex[1]; index[2] = (float)vertex[2]; if (geom->IsIndexInside(index)) { geom->IndexToWorld(index, point); vtkIdType id = vPoints->InsertNextPoint(point.GetDataPointer()); vPolyLine->GetPointIds()->InsertNextId(id); } else { addTract = false; break; } } if (addTract) vCellArray->InsertNextCell(vPolyLine); ++elIt; } } ++it; } vtkSmartPointer fiberPolyData = vtkSmartPointer::New(); fiberPolyData->SetPoints(vPoints); fiberPolyData->SetLines(vCellArray); mitk::FiberBundleX::Pointer fib = mitk::FiberBundleX::New(fiberPolyData); mitk::DataNode::Pointer fbNode = mitk::DataNode::New(); fbNode->SetData(fib); QString name("FiberBundle_"); name += m_DiffusionImageNode->GetName().c_str(); name += "_Probabilistic"; fbNode->SetName(name.toStdString()); fbNode->SetVisibility(true); GetDataStorage()->Add(fbNode, m_DiffusionImageNode); }