diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/berryExtensionType.cpp b/BlueBerry/Bundles/org.blueberry.osgi/src/berryExtensionType.cpp index ab066aaac6..c87827ce46 100644 --- a/BlueBerry/Bundles/org.blueberry.osgi/src/berryExtensionType.cpp +++ b/BlueBerry/Bundles/org.blueberry.osgi/src/berryExtensionType.cpp @@ -1,202 +1,202 @@ /*========================================================================= Program: BlueBerry Platform Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "berryExtensionType.h" #include #include #include namespace berry { class CustomTypeInfo { public: CustomTypeInfo() : typeName(), constr(0), destr(0) {} QByteArray typeName; ExtensionType::Constructor constr; ExtensionType::Destructor destr; int alias; }; //Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE); Q_GLOBAL_STATIC(QVector, customTypes) Q_GLOBAL_STATIC(QReadWriteLock, customTypesLock) const char* ExtensionType::typeName(int type) { const QVector* const ct = customTypes(); QReadLocker locker(customTypesLock()); return ct && ct->count() > type && !ct->at(type).typeName.isEmpty() ? ct->at(type).typeName.constData() : static_cast(0); } /*! \internal Similar to ExtensionType::type(), but doesn't lock the mutex. */ static int extensionTypeCustomType_unlocked(const char *typeName, int length) { const QVector* const ct = customTypes(); if (!ct) return 0; for (int v = 0; v < ct->count(); ++v) { const CustomTypeInfo& customInfo = ct->at(v); if ((length == customInfo.typeName.size()) && !std::strcmp(typeName, customInfo.typeName.constData())) { if (customInfo.alias >= 0) return customInfo.alias; return v+1; } } return 0; } int ExtensionType::registerType(const char *typeName, Destructor destructor, Constructor constructor) { QVector* ct = customTypes(); if (!ct || !typeName || !destructor || !constructor) return -1; QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName); QWriteLocker locker(customTypesLock()); int idx = extensionTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); if (!idx) { CustomTypeInfo inf; inf.typeName = normalizedTypeName; inf.constr = constructor; inf.destr = destructor; inf.alias = -1; idx = ct->size(); ct->append(inf); } return idx; } int ExtensionType::registerTypedef(const char* typeName, int aliasId) { QVector* ct = customTypes(); if (!ct || !typeName) return -1; QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName); QWriteLocker locker(customTypesLock()); int idx = extensionTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); if (idx) return idx; CustomTypeInfo inf; inf.typeName = normalizedTypeName; inf.alias = aliasId; inf.constr = 0; inf.destr = 0; ct->append(inf); return aliasId; } void ExtensionType::unregisterType(const char* typeName) { QVector *ct = customTypes(); if (!ct || !typeName) return; QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName); QWriteLocker locker(customTypesLock()); for (int v = 0; v < ct->count(); ++v) { if (ct->at(v).typeName == typeName) { CustomTypeInfo &inf = (*ct)[v]; inf.typeName.clear(); inf.constr = 0; inf.destr = 0; inf.alias = -1; } } } bool ExtensionType::isRegistered(int type) { QReadLocker locker(customTypesLock()); const QVector* const ct = customTypes(); return ((type > 0) && (ct && ct->count() > type - 1) && !ct->at(type - 1).typeName.isEmpty()); } int ExtensionType::type(const char *typeName) { - int length = std::strlen(typeName); + int length = static_cast(std::strlen(typeName)); if (!length) return 0; QReadLocker locker(customTypesLock()); int type = extensionTypeCustomType_unlocked(typeName, length); if (!type) { const QByteArray normalizedTypeName = QMetaObject::normalizedType(typeName); type = extensionTypeCustomType_unlocked(normalizedTypeName.constData(), normalizedTypeName.size()); } return type; } QObject* ExtensionType::construct(int type) { const QVector * const ct = customTypes(); Constructor constr = 0; QReadLocker locker(customTypesLock()); if (!ct || ct->count() <= type - 1) return 0; if (ct->at(type - 1).typeName.isEmpty()) return 0; constr = ct->at(type - 1).constr; return constr(); } void ExtensionType::destroy(int type, QObject* data) { if (!data) return; const QVector * const ct = customTypes(); if (!ct || ct->count() <= type - 1) return; Destructor destr = 0; QReadLocker locker(customTypesLock()); if (ct->at(type - 1).typeName.isEmpty()) return; destr = ct->at(type - 1).destr; destr(data); } } // end namespace berry diff --git a/CMake/mitkFunctionSuppressWarnings.cmake b/CMake/mitkFunctionSuppressWarnings.cmake index bfe61e569c..be93a6692e 100644 --- a/CMake/mitkFunctionSuppressWarnings.cmake +++ b/CMake/mitkFunctionSuppressWarnings.cmake @@ -1,21 +1,21 @@ # suppress some warnings in VC8 about using unsafe/deprecated c functions -function(SUPPRESS_VC8_DEPRECATED_WARNINGS) - if(MSVC80) - add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS) +function(SUPPRESS_VC_DEPRECATED_WARNINGS) + if(MSVC) + add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) endif() endfunction() function(SUPPRESS_ALL_WARNINGS) if(MSVC) string(REGEX REPLACE "/W[0-9]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) string(REGEX REPLACE "/W[0-9]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) add_definitions(/w) # suppress also poco linker warnings set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /ignore:4217") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /ignore:4217") elseif(CMAKE_COMPILER_IS_GNUCXX) add_definitions(-w) endif() endfunction(SUPPRESS_ALL_WARNINGS) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4edd4e38cb..2da8e6e4ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,760 +1,763 @@ cmake_minimum_required(VERSION 2.8.4) #----------------------------------------------------------------------------- # 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() #----------------------------------------------------------------------------- # 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) # some targets in Utilities also depend on Qt. Use this option # to decide if they should be build option(MITK_USE_QT "Use Trolltech's Qt library" ON) if(MITK_USE_QT) # find the package at the very beginning, so that QT4_FOUND is available find_package(Qt4 4.6.0 REQUIRED) endif() option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) option(MITK_BUILD_TUTORIAL "Build the MITK tutorial" ON) option(MITK_USE_Boost "Use the Boost C++ library" OFF) 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() option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_BLUEBERRY}) option(MITK_USE_DCMTK "EXEPERIMENTAL, superbuild only: Use DCMTK in MITK" OFF) option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF) option(MITK_USE_Python "Use Python wrapping in MITK" OFF) mark_as_advanced(MITK_BUILD_ALL_PLUGINS MITK_BUILD_ALL_APPS MITK_USE_CTK MITK_USE_DCMTK ) 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 "" 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(MITK_USE_BLUEBERRY AND NOT MITK_USE_CTK) MESSAGE(FATAL_ERROR "BlueBerry depends on CTK. Please set MITK_USE_CTK to ON.") endif() 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_DIMENSIONS) set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") endif() #----------------------------------------------------------------------------- # Additional CXX/C Flags #----------------------------------------------------------------------------- set(ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags") mark_as_advanced(ADDITIONAL_C_FLAGS) set(ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags") mark_as_advanced(ADDITIONAL_CXX_FLAGS) #----------------------------------------------------------------------------- # 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 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(mitkFunctionCreateWindowsBatchScript) include(mitkFunctionInstallProvisioningFiles) 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) if(ITK_USE_SYSTEM_GDCM) find_package(GDCM PATHS ${ITK_GDCM_DIR} REQUIRED) endif() #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- # ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and ExtApp 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") set(MITK_FAST_TESTING 1) endif() endif() #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${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(APPLE) if(MITK_BUILD_org.mitk.gui.qt.extapplication) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} ExtApp) endif() if(MITK_BUILD_org.mitk.gui.qt.application) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} CoreApp) endif() endif(APPLE) #----------------------------------------------------------------------------- # 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} ${ADDITIONAL_C_FLAGS}") set(MITK_CXX_FLAGS "${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS} ${ADDITIONAL_CXX_FLAGS}") include(mitkSetupC++0xVariables) if(CMAKE_COMPILER_IS_GNUCXX) set(cflags "-Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -D_FORTIFY_SOURCE=2") mitkFunctionCheckCompilerFlags("-fdiagnostics-show-option" cflags) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" cflags) 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")) mitkFunctionCheckCompilerFlags("-fstack-protector-all" cflags) endif() if(MINGW) # suppress warnings about auto imported symbols set(MITK_CXX_FLAGS "-Wl,--enable-auto-import ${MITK_CXX_FLAGS}") # we need to define a Windows version set(MITK_CXX_FLAGS "-D_WIN32_WINNT=0x0500 ${MITK_CXX_FLAGS}") endif() set(MITK_C_FLAGS "${cflags} ${MITK_C_FLAGS}") #set(MITK_CXX_FLAGS "${cflags} -Woverloaded-virtual -Wold-style-cast -Wstrict-null-sentinel -Wsign-promo ${MITK_CXX_FLAGS}") set(MITK_CXX_FLAGS "${cflags} -Woverloaded-virtual -Wstrict-null-sentinel ${MITK_CXX_FLAGS}") endif() #----------------------------------------------------------------------------- # 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} 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() include(mitkSetupBlueBerry) endif() #----------------------------------------------------------------------------- # Set C/CXX Flags for MITK code #----------------------------------------------------------------------------- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_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) if(MITK_USE_QT AND QT4_FOUND) add_subdirectory(CoreUI/Qmitk) endif() add_subdirectory(Modules) if(MITK_USE_BLUEBERRY) find_package(BlueBerry REQUIRED) set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins) include("${CMAKE_CURRENT_SOURCE_DIR}/CoreUI/Bundles/PluginList.cmake") set(mitk_core_plugins_fullpath ) foreach(core_plugin ${MITK_CORE_PLUGINS}) list(APPEND mitk_core_plugins_fullpath CoreUI/Bundles/${core_plugin}) endforeach() if(BUILD_TESTING) include(berryTestingHelpers) include("${CMAKE_CURRENT_SOURCE_DIR}/CoreUI/BundleTesting/PluginList.cmake") set(mitk_core_test_plugins_fullpath ) foreach(core_test_plugin ${MITK_CORE_TEST_PLUGINS}) # list(APPEND mitk_core_test_plugins_fullpath CoreUI/BundleTesting/${core_test_plugin}) endforeach() 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.application") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/Modules/Bundles/PluginList.cmake") set(mitk_ext_plugins_fullpath ) foreach(ext_plugin ${MITK_EXT_PLUGINS}) list(APPEND mitk_ext_plugins_fullpath Modules/Bundles/${ext_plugin}) endforeach() if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake) include(${MITK_PRIVATE_MODULES}/PluginList.cmake) foreach(ext_plugin ${MITK_PRIVATE_PLUGINS}) list(APPEND mitk_ext_plugins_fullpath ${MITK_PRIVATE_MODULES}/${ext_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() # Add the BlueBerry plugins to the set of core plugins set(MITK_CORE_ENABLED_PLUGINS ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES}) # 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_core_plugins_fullpath} ${mitk_core_test_plugins_fullpath} ${mitk_ext_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) ctkFunctionExtractPluginTargets("${mitk_core_plugins_fullpath}" ON _coreui_plugins) list(APPEND MITK_CORE_ENABLED_PLUGINS ${_coreui_plugins}) 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() # add legacy BlueBerry bundles add_subdirectory(Modules/Bundles) 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_LIBRARY_DIRS}/@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() # 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 #----------------------------------------------------------------------------- set(MITK_WRAPPING_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Wrapping) set(MITK_WRAPPING_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Wrapping) option(MITK_USE_Python "Build cswig Python wrapper support (requires CableSwig)." OFF) if(MITK_USE_Python) add_subdirectory(Wrapping) endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- add_subdirectory(Documentation) #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables include(mitkSetupCPack) if(MITK_BUILD_org.mitk.gui.qt.application) list(APPEND CPACK_CREATE_DESKTOP_LINKS "CoreApp") endif() if(MITK_BUILD_org.mitk.gui.qt.extapplication) list(APPEND CPACK_CREATE_DESKTOP_LINKS "ExtApp") endif() configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake") # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake") file(REMOVE ${MITK_EXPORTS_FILE}) if(MITK_USE_BLUEBERRY) # This is for installation support of external projects depending on # MITK plugins. 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). if(MITK_PLUGIN_LIBRARIES) export(TARGETS ${MITK_PLUGIN_LIBRARIES} APPEND FILE ${MITK_EXPORTS_FILE}) endif() endif() configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY) configure_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) diff --git a/Core/Code/Controllers/mitkCallbackFromGUIThread.h b/Core/Code/Controllers/mitkCallbackFromGUIThread.h index 6c075c9d1f..90e44c8155 100644 --- a/Core/Code/Controllers/mitkCallbackFromGUIThread.h +++ b/Core/Code/Controllers/mitkCallbackFromGUIThread.h @@ -1,207 +1,205 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITK_CALLBACK_WITHIN_GUI_TREAD_H_INCLUDGEWQ #define MITK_CALLBACK_WITHIN_GUI_TREAD_H_INCLUDGEWQ #include -#pragma GCC visibility push(default) #include -#pragma GCC visibility pop #include namespace mitk { /*! \brief Used by CallbackFromGUIThread to pass parameters. */ template class CallbackEventOneParameter : public itk::AnyEvent { public: typedef CallbackEventOneParameter Self; typedef itk::AnyEvent Superclass; CallbackEventOneParameter(const T t ) : m_Data(t) {} virtual ~CallbackEventOneParameter() {} virtual const char * GetEventName() const { return "CallbackEventOneParameter"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self( m_Data ); } const T GetData() const { return m_Data; } CallbackEventOneParameter(const Self& s) : itk::AnyEvent(s), m_Data(s.m_Data) {}; protected: const T m_Data; private: void operator=(const Self&); }; /*! \brief Toolkit specific implementation of mitk::CallbackFromGUIThread For any toolkit, this class has to be sub-classed. One instance of that sub-class has to be registered with mitk::CallbackFromGUIThread. See the (very simple) implmentation of QmitkCallbackFromGUIThread for an example. */ class MITK_CORE_EXPORT CallbackFromGUIThreadImplementation { public: /// Change the current application cursor virtual void CallThisFromGUIThread(itk::Command*, itk::EventObject*) = 0; virtual ~CallbackFromGUIThreadImplementation() {}; protected: private: }; /*! \brief Allows threads to call some method from within the GUI thread. This class is useful for use with GUI toolkits that are not thread-safe, e.g. Qt. Any thread that needs to work with the GUI at some time during its execution (e.g. at the end, to display some results) can use this class to ask for a call to a member function from the GUI thread. Usage example We assume that you have a class ThreadedClass, that basically lives in a thread that is different from the GUI thread. Now this class has to change some element of the GUI to indicate its status. This could be dangerous (with Qt it is for sure). The solution is, that ThreadedClass asks mitk::CallbackFromGUIThread to call a method from the GUI thread (main thread). Here is part of the header of ThreadedClass: \code class ThreadedClass : public ParentClass { public: ... // All you need // This function runs in its own thread ! void ThreadedFunction(); // This should be called from the GUI thread void ChangeGUIElementsToIndicateProgress(const itk::EventObject&); ... }; \endcode \code #include "mitkCallbackFromGUIThread.h" #include // This method runs in a thread of its own! So it can't manipulate GUI elements directly without causing trouble void ThreadedClass::ThreadedFunction() { ... // Create a command object (passing parameters comes later) itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &ThreadedClass::ChangeGUIElementsToIndicateProgress); // Ask to execute that command from the GUI thread mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(command); ... } // Do dangerous GUI changing stuff here void ThreadedClass::ChangeGUIElementsToIndicateProgress(const itk::EventObject& e) { Application::GetButtonGrid()->AddButton("Stop"); // this is pseudo code } \endcode This obviously won't allow you to pass parameters to ChangeGUIElementsToIndicateProgress. If you need to do that, you have to create a kind of itk::EventObject that can be asked for a parameter (this solution is not nice, if you see a better solution, please mail to mitk-users@lists.sourceforge.net). The itk::EventObject has to be created with "new" (which can also be done by calling MakeObject on an existing EventObject). \code const mitk::OneParameterEvent* event = new mitk::OneParameterEvent(1); // this class is not yet defined but will be itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &ThreadedClass::ChangeGUIElementsToIndicateProgress); mitk::CallbackFromGUIThread::GetInstance()->CallThisFromGUIThread(command, event); // DO NOT delete event now. This will be done by CallThisFromGUIThread after the command will executed. \endcode \todo Create a set of "normal" parameter-event-objects that people might want to use. */ class MITK_CORE_EXPORT CallbackFromGUIThread { public: /// This class is a singleton. static CallbackFromGUIThread* GetInstance(); /// To be called by a toolkit specific CallbackFromGUIThreadImplementation. static void RegisterImplementation(CallbackFromGUIThreadImplementation* implementation); /// Change the current application cursor void CallThisFromGUIThread(itk::Command*, itk::EventObject* e = NULL); protected: /// Purposely hidden - singleton CallbackFromGUIThread(); private: static CallbackFromGUIThreadImplementation* m_Implementation; static CallbackFromGUIThread* m_Instance; }; } // namespace #endif diff --git a/Core/Code/Controllers/mitkVtkLayerController.h b/Core/Code/Controllers/mitkVtkLayerController.h index e66d9ad15e..c2b8d33d24 100644 --- a/Core/Code/Controllers/mitkVtkLayerController.h +++ b/Core/Code/Controllers/mitkVtkLayerController.h @@ -1,127 +1,135 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D #define MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D #include #include #include class vtkRenderWindow; class vtkRenderer; namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4251) +#endif /** * Manages the VTK layer hierarchy * of a vtkRenderWindow. * For simple access the layers are divided into three * main groups: background, scene and foreground layers. * Renderers can be registered via the insert... functions and * removed via the RemoveRenderer function. */ class MITK_CORE_EXPORT VtkLayerController { public: static VtkLayerController* GetInstance(vtkRenderWindow* renWin); static void AddInstance(vtkRenderWindow* renWin, vtkRenderer * mitkSceneRenderer); static void RemoveInstance(vtkRenderWindow* renWin); VtkLayerController(vtkRenderWindow* renderWindow); virtual ~VtkLayerController(); /** * Returns the current vtkRenderer of the Scene */ vtkRenderer* GetSceneRenderer(); /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the background. * With forceAbsoluteBackground set true a renderer can be placed at the absolute background of the scene. * Multiple calls with forceAbsoluteBackground set true will set the latest registered renderer as background. */ void InsertBackgroundRenderer(vtkRenderer* renderer, bool forceAbsoluteBackground); /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered in the foreground. * With forceAbsoluteBackground set true a renderer can be placed at the absolute foreground of the scene. * Multiple calls with forceAbsoluteForeground set true will set the latest registered renderer as foreground. */ void InsertForegroundRenderer(vtkRenderer* renderer, bool forceAbsoluteForeground); /** * Connects a VTK renderer with a vtk renderwindow. The renderer will be rendered between background renderers and * foreground renderers. */ void InsertSceneRenderer(vtkRenderer* renderer); /** * Connects a VtkRenderWindow with the layer controller. */ void SetRenderWindow(vtkRenderWindow* renwin); /** * A renderer which has been inserted via a insert... function can be removed from the vtkRenderWindow with * RemoveRenderer. */ void RemoveRenderer(vtkRenderer* renderer); /** * Returns true if a renderer has been inserted */ bool IsRendererInserted(vtkRenderer* renderer); /** * Returns the number of renderers in the renderwindow. */ unsigned int GetNumberOfRenderers(); void SetEraseForAllRenderers(int i); protected: vtkRenderWindow* m_RenderWindow; private: /** * Internally used to sort all registered renderers and to connect the with the vtkRenderWindow. * Mention that VTK Version 5 and above is rendering higher numbers in the background and VTK * Verison < 5 in the foreground. */ void UpdateLayers(); // Layer Management typedef std::vector RendererVectorType; RendererVectorType m_BackgroundRenderers; RendererVectorType m_SceneRenderers; RendererVectorType m_ForegroundRenderers; typedef std::map vtkLayerControllerMapType; static vtkLayerControllerMapType s_LayerControllerMap; }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // Namespace MITK #endif /* MITKVTKLAYERCONTROLLER_H_HEADER_INCLUDED_C1EDO02D */ diff --git a/Core/Code/DataManagement/mitkClippingProperty.h b/Core/Code/DataManagement/mitkClippingProperty.h index 15eb5ff31a..4e5a1b540b 100644 --- a/Core/Code/DataManagement/mitkClippingProperty.h +++ b/Core/Code/DataManagement/mitkClippingProperty.h @@ -1,85 +1,94 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $ Version: $Revision: 14081 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED #define MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED #include #include "mitkBaseProperty.h" #include "mitkVector.h" #include #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * \brief Property for clipping datasets; currently only * clipping planes are possible * \ingroup DataManagement */ class MITK_CORE_EXPORT ClippingProperty : public BaseProperty { public: mitkClassMacro(ClippingProperty, BaseProperty); typedef std::string ValueType; itkNewMacro( ClippingProperty ); mitkNewMacro2Param( ClippingProperty, const Point3D &, const Vector3D & ); bool GetClippingEnabled() const; void SetClippingEnabled( bool enabled ); const Point3D &GetOrigin() const; void SetOrigin( const Point3D &origin ); const Vector3D &GetNormal() const; void SetNormal( const Vector3D &normal ); virtual std::string GetValueAsString() const; using BaseProperty::operator =; protected: bool m_ClippingEnabled; Point3D m_Origin; Vector3D m_Normal; ClippingProperty(); ClippingProperty( const Point3D &origin, const Vector3D &normal ); private: // purposely not implemented ClippingProperty(const ClippingProperty&); ClippingProperty& operator=(const ClippingProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKCLIPPINGPROPERTY_H_HEADER_INCLUDED */ diff --git a/Core/Code/DataManagement/mitkColorProperty.h b/Core/Code/DataManagement/mitkColorProperty.h index 311da9e436..bf91857af8 100644 --- a/Core/Code/DataManagement/mitkColorProperty.h +++ b/Core/Code/DataManagement/mitkColorProperty.h @@ -1,85 +1,94 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #define MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 #include #include "mitkBaseProperty.h" #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + //##Documentation //## @brief Standard RGB color typedef (float) //## //## Standard RGB color typedef to get rid of template argument (float). //## @ingroup Property typedef itk::RGBPixel< float > Color; //##Documentation //## @brief RGB color property //## //## @ingroup DataManagement class MITK_CORE_EXPORT ColorProperty : public BaseProperty { protected: mitk::Color m_Color; ColorProperty(); ColorProperty(const float red, const float green, const float blue); ColorProperty(const float color[3]); ColorProperty(const mitk::Color & color); public: mitkClassMacro(ColorProperty, BaseProperty); itkNewMacro(ColorProperty); mitkNewMacro1Param(ColorProperty, const float*); mitkNewMacro1Param(ColorProperty, const mitk::Color&); mitkNewMacro3Param(ColorProperty, const float, const float, const float); typedef mitk::Color ValueType; const mitk::Color & GetColor() const; const mitk::Color & GetValue() const; std::string GetValueAsString() const; void SetColor(const mitk::Color & color ); void SetValue(const mitk::Color & color ); void SetColor( float red, float green, float blue ); using BaseProperty::operator=; private: // purposely not implemented ColorProperty(const ColorProperty&); ColorProperty& operator=(const ColorProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty & property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKCOLORPROPERTY_H_HEADER_INCLUDED_C17953D1 */ diff --git a/Core/Code/DataManagement/mitkEnumerationProperty.h b/Core/Code/DataManagement/mitkEnumerationProperty.h index b567e796eb..04db8b1c8c 100644 --- a/Core/Code/DataManagement/mitkEnumerationProperty.h +++ b/Core/Code/DataManagement/mitkEnumerationProperty.h @@ -1,218 +1,226 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_ENUMERATION_PROPERTY__H_ #define _MITK_ENUMERATION_PROPERTY__H_ #include "mitkBaseProperty.h" #include #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * This class may be used to store properties similar to enumeration values. * Each enumeration value is identified via a string representation and a * id. Note, that both string representation and id MUST be unique. This is checked * when inserting a new enumeration value. Please note that you have to add valid * enumeration values before you may use the Get/SetValue methods. * * To use the class enumeration property you have 2 choices: * * 1. Directly use the class and add your possible enumeration values via * AddEnum(name, id). NOte that the ids do not have to be in any order, they * just have to be unique. The current value is set via SetValue(...) and * retrieved via GetValueAsId() or GetValueAsString(). * 2. Create a subclass, which adds the possible enumeration values in its * constructor and maybe adds some additional convenience functions to * set/get the value. NOte that you should override AddEnum(...) as protected * so that the user may not add additional invalid enumeration values. * As example see mitk::VtkRepresentationProperty or mitk::VtkInterpolationProperty * * @ingroup DataManagement */ class MITK_CORE_EXPORT EnumerationProperty : public BaseProperty { public: mitkClassMacro( EnumerationProperty, BaseProperty ); itkNewMacro(EnumerationProperty); /** * Represents the unique id which is asigned to each enumeration value */ typedef unsigned int IdType; /** * Type used to store a mapping from enumeration id to enumeration string/ * description */ typedef std::map EnumIdsContainerType; /** * Type used to store a mapping from enumeration string/description to * enumeration id */ typedef std::map EnumStringsContainerType; /** * Type used for iterators over all defined enumeration values. */ typedef EnumIdsContainerType::const_iterator EnumConstIterator; /** * Adds an enumeration value into the enumeration. The name and id provided * must be unique. This is checked while adding the new enumeration value. * If it is not unique, false is returned. If addition was successful, true * is returned. * @param name the unique string representation of the enumeration value * @param id the unique integer representation of the enumeration value * @returns true, if the name/id combination was successfully added to the * enumeration values or true otherwise */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Sets the current value of the enumeration * @param name the string representation of the enumeration value to set * @returns true if the value was successfully set (i.e. it was valid), or * false, if the name provided is incalid. */ virtual bool SetValue( const std::string& name ); /** * Sets the current value of the enumeration * @param id the integer representation of the enumeration value to set * @returns true if the value was successfully set (i.e. it was valid), or * false, if the id provided is invalid. */ virtual bool SetValue( const IdType& id ); /** * Returns the id of the current enumeration value. If it was not yet set, * the return value is unspecified */ virtual IdType GetValueAsId() const; /** * Returns the string representation of the current enumeration value. If it * was not yet set, the return value is unspecified */ virtual std::string GetValueAsString() const; /** * Clears all possible enumeration values and the current enumeration value. */ virtual void Clear(); /** * Determines the number of enumeration values which have been added via * AddEnum(...). * @returns the number of enumeration values associated with this Enumeration * Property */ virtual EnumIdsContainerType::size_type Size() const; /** * Provides access to the set of known enumeration values. The string representation * may be accessed via iterator->second, the id may be access via iterator->first * @returns an iterator over all enumeration values. */ virtual EnumConstIterator Begin() const; /** * Specifies the end of the range of the known enumeration values. * @returns an iterator pointing past the last known element of the possible * enumeration values. */ virtual EnumConstIterator End() const; /** * Returns the string representation for the given id. * @param id the id for which the string representation should be determined * if id is invalid, the return value is unspecified. * @returns the string representation of the given enumeration value */ virtual std::string GetEnumString( const IdType& id ) const; /** * Returns the integer representation for the given string. * @param name the enumeration name for which the integer representation should be determined * if the name is invalid, the return value is unspecified. * @returns the integer representation of the given enumeration value */ virtual IdType GetEnumId( const std::string& name ) const; /** * Determines if a given integer representation of an enumeration value * is valid or not * @param val the integer value to check * @returns true if the given value is valid or false otherwise */ virtual bool IsValidEnumerationValue( const IdType& val ) const; /** * Determines if a given string representation of an enumeration value * is valid or not * @param val the string to check * @returns true if the given value is valid or false otherwise */ virtual bool IsValidEnumerationValue( const std::string& val ) const; const EnumIdsContainerType& GetEnumIds() const; const EnumStringsContainerType& GetEnumStrings() const; EnumIdsContainerType& GetEnumIds(); EnumStringsContainerType& GetEnumStrings(); using BaseProperty::operator=; protected: /** * Default constructor. The current value of the enumeration is undefined. */ EnumerationProperty(); virtual bool IsEqual( const BaseProperty& property ) const; virtual bool Assign( const BaseProperty& property ); private: // purposely not implemented EnumerationProperty(const EnumerationProperty&); EnumerationProperty& operator=(const EnumerationProperty&); IdType m_CurrentValue; typedef std::map IdMapForClassNameContainerType; typedef std::map StringMapForClassNameContainerType; static IdMapForClassNameContainerType s_IdMapForClassName; static StringMapForClassNameContainerType s_StringMapForClassName; }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif } // namespace #endif diff --git a/Core/Code/DataManagement/mitkGenericProperty.h b/Core/Code/DataManagement/mitkGenericProperty.h index b06430e7ed..8d8778afde 100644 --- a/Core/Code/DataManagement/mitkGenericProperty.h +++ b/Core/Code/DataManagement/mitkGenericProperty.h @@ -1,119 +1,128 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE #define MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE #include #include #include #include "mitkVector.h" #include #include "mitkBaseProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /*! @ brief Template class for generating properties for int, float, bool, etc. This class template can be instantiated for all classes/internal types that fulfills these requirements: - an operator<< so that the properties value can be put into a std::stringstream - an operator== so that two properties can be checked for equality Note: you must use the macro mitkSpecializeGenericProperty to provide specializations for concrete types (e.g. BoolProperty). Please see mitkProperties.h for examples. If you don't use the mitkSpecializeGenericProperty Macro, GetNameOfClass() returns a wrong name. */ template class MITK_EXPORT GenericProperty : public BaseProperty { public: mitkClassMacro(GenericProperty, BaseProperty); mitkNewMacro1Param(GenericProperty, T); typedef T ValueType; itkSetMacro(Value,T); itkGetConstMacro(Value,T); virtual std::string GetValueAsString() const { std::stringstream myStr; myStr << GetValue() ; return myStr.str(); } using BaseProperty::operator=; protected: GenericProperty() {} GenericProperty(T x) : m_Value(x) {} T m_Value; private: // purposely not implemented GenericProperty(const GenericProperty&); GenericProperty& operator=(const GenericProperty&); virtual bool IsEqual(const BaseProperty& other) const { return (this->m_Value == static_cast(other).m_Value); } virtual bool Assign(const BaseProperty& other) { this->m_Value = static_cast(other).m_Value; return true; } }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk /** * Generates a specialized subclass of mitk::GenericProperty. * This way, GetNameOfClass() returns the value provided by PropertyName. * Please see mitkProperties.h for examples. * @param PropertyName the name of the subclass of GenericProperty * @param Type the value type of the GenericProperty * @param Export the export macro for DLL usage */ #define mitkDeclareGenericProperty(PropertyName,Type,Export) \ class Export PropertyName: public GenericProperty< Type > \ { \ public: \ mitkClassMacro(PropertyName, GenericProperty< Type >); \ itkNewMacro(PropertyName); \ mitkNewMacro1Param(PropertyName, Type); \ using BaseProperty::operator=; \ protected: \ PropertyName(); \ PropertyName(Type x); \ }; #define mitkDefineGenericProperty(PropertyName,Type,DefaultValue) \ mitk::PropertyName::PropertyName() : Superclass(DefaultValue) { } \ mitk::PropertyName::PropertyName(Type x) : Superclass(x) {} #endif /* MITKGENERICPROPERTY_H_HEADER_INCLUDED_C1061CEE */ diff --git a/Core/Code/DataManagement/mitkGroupTagProperty.h b/Core/Code/DataManagement/mitkGroupTagProperty.h index cdd3c8d30c..ea5076ece1 100644 --- a/Core/Code/DataManagement/mitkGroupTagProperty.h +++ b/Core/Code/DataManagement/mitkGroupTagProperty.h @@ -1,59 +1,68 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54 #define GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54 #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /*! @brief Property class that has no value. @ingroup DataManagement The GroupTag property is used to tag a datatree node to show, that it is member of a group of datatree nodes. This can be used to build groups of datatreenodes without the need to contain them in a specific hiearchic order in the datatree */ class MITK_CORE_EXPORT GroupTagProperty : public BaseProperty { public: mitkClassMacro(GroupTagProperty, BaseProperty); itkNewMacro(GroupTagProperty); using BaseProperty::operator=; protected: GroupTagProperty(); private: // purposely not implemented GroupTagProperty(const GroupTagProperty&); GroupTagProperty& operator=(const GroupTagProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* GROUPTAGPROPERTY_H_HEADER_INCLUDED_C1F4DF54 */ diff --git a/Core/Code/DataManagement/mitkLevelWindowProperty.h b/Core/Code/DataManagement/mitkLevelWindowProperty.h index db23f5216f..6320fd1e37 100755 --- a/Core/Code/DataManagement/mitkLevelWindowProperty.h +++ b/Core/Code/DataManagement/mitkLevelWindowProperty.h @@ -1,76 +1,85 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8 #define MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8 #include "mitkBaseProperty.h" #include "mitkLevelWindow.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + //##Documentation //## @brief Property for level/window data //## //## @ingroup DataManagement class MITK_CORE_EXPORT LevelWindowProperty : public BaseProperty { protected: LevelWindow m_LevWin; LevelWindowProperty(); LevelWindowProperty(const mitk::LevelWindow &levWin); public: mitkClassMacro(LevelWindowProperty, BaseProperty); itkNewMacro(LevelWindowProperty); mitkNewMacro1Param(LevelWindowProperty, const mitk::LevelWindow&); typedef LevelWindow ValueType; virtual ~LevelWindowProperty(); const mitk::LevelWindow & GetLevelWindow() const; const mitk::LevelWindow & GetValue() const; void SetLevelWindow(const LevelWindow &levWin); void SetValue(const ValueType& levWin); virtual std::string GetValueAsString() const; using BaseProperty::operator=; private: // purposely not implemented LevelWindowProperty(const LevelWindowProperty&); LevelWindowProperty& operator=(const LevelWindowProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKLEVELWINDOWPROPERTY_H_HEADER_INCLUDED_C10EEAA8 */ diff --git a/Core/Code/DataManagement/mitkModalityProperty.cpp b/Core/Code/DataManagement/mitkModalityProperty.cpp index 0ecaa6a13c..bdbae6bd48 100644 --- a/Core/Code/DataManagement/mitkModalityProperty.cpp +++ b/Core/Code/DataManagement/mitkModalityProperty.cpp @@ -1,71 +1,71 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-17 13:14:37 +0100 (Di, 17 Feb 2009) $ Version: $Revision: 16318 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkModalityProperty.h" mitk::ModalityProperty::ModalityProperty() { AddEnumerationTypes(); } mitk::ModalityProperty::ModalityProperty( const IdType& value ) { AddEnumerationTypes(); if ( IsValidEnumerationValue( value ) ) { SetValue( value ) ; } else { SetValue( 0 ); } } mitk::ModalityProperty::ModalityProperty( const std::string& value ) { AddEnumerationTypes(); if ( IsValidEnumerationValue( value ) ) { SetValue( value ); } else { SetValue( "undefined" ); } } mitk::ModalityProperty::~ModalityProperty() { } void mitk::ModalityProperty::AddEnumerationTypes() { - IdType newId = EnumerationProperty::Size(); + IdType newId = static_cast(EnumerationProperty::Size()); AddEnum( "undefined", newId++ ); AddEnum( "CR", newId++ ); // computer radiography AddEnum( "CT", newId++ ); // computed tomography AddEnum( "MR", newId++ ); // magnetic resonance AddEnum( "NM", newId++ ); // nuclear medicine AddEnum( "US", newId++ ); // ultrasound AddEnum( "Color Doppler", newId++ ); // ultrasound AddEnum( "Power Doppler", newId++ ); // ultrasound } diff --git a/Core/Code/DataManagement/mitkModalityProperty.h b/Core/Code/DataManagement/mitkModalityProperty.h index 8d1d358275..2f6279939f 100644 --- a/Core/Code/DataManagement/mitkModalityProperty.h +++ b/Core/Code/DataManagement/mitkModalityProperty.h @@ -1,63 +1,72 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-15 10:46:54 +0200 (Fr, 15 Mai 2009) $ Version: $Revision: 17272 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef mitkModalityProperty_h_Included #define mitkModalityProperty_h_Included #include #include "mitkEnumerationProperty.h" #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** \brief Enumerates all known modalities \ingroup DataManagement */ class MITK_CORE_EXPORT ModalityProperty : public EnumerationProperty { public: mitkClassMacro(ModalityProperty, EnumerationProperty); itkNewMacro(ModalityProperty); mitkNewMacro1Param(ModalityProperty, const IdType&); mitkNewMacro1Param(ModalityProperty, const std::string&); using BaseProperty::operator=; protected: ModalityProperty(); ModalityProperty( const IdType& value ); ModalityProperty( const std::string& value ); virtual ~ModalityProperty(); virtual void AddEnumerationTypes(); private: // purposely not implemented ModalityProperty(const ModalityProperty&); const ModalityProperty& operator=(const ModalityProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace #endif diff --git a/Core/Code/DataManagement/mitkPlaneOrientationProperty.h b/Core/Code/DataManagement/mitkPlaneOrientationProperty.h index f0a048ca86..0f2db713df 100644 --- a/Core/Code/DataManagement/mitkPlaneOrientationProperty.h +++ b/Core/Code/DataManagement/mitkPlaneOrientationProperty.h @@ -1,121 +1,130 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $ Version: $Revision: 14081 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITK_PLANE_DECORATION_PROPERTY__H #define MITK_PLANE_DECORATION_PROPERTY__H #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Property which controls whether 2D line representation of a PlaneGeometry * should have small arrows at both ends to indicate the orientation of * the plane, and whether the arrows should be oriented in the direction of * the plane's normal or against it. * * Valid values of the enumeration property are * - PLANE_DECORATION_NONE (no arrows) * - PLANE_DECORATION_POSITIVE_ORIENTATION (arrows pointing upwards) * - PLANE_DECORATION_NEGATIVE_ORIENTATION (arrows pointing downwards) * * See also mitk::Geometry2DDataMapper2D::DrawOrientationArrow() */ class MITK_CORE_EXPORT PlaneOrientationProperty : public EnumerationProperty { public: mitkClassMacro( PlaneOrientationProperty, EnumerationProperty ); itkNewMacro(PlaneOrientationProperty); mitkNewMacro1Param(PlaneOrientationProperty, const IdType&); mitkNewMacro1Param(PlaneOrientationProperty, const std::string&); enum { PLANE_DECORATION_NONE, PLANE_DECORATION_POSITIVE_ORIENTATION, PLANE_DECORATION_NEGATIVE_ORIENTATION }; /** * Returns the state of plane decoration. */ virtual int GetPlaneDecoration(); /** * Sets the decoration type to no decoration. */ virtual void SetPlaneDecorationToNone(); /** * Sets the decoration type to arrows in positive plane direction. */ virtual void SetPlaneDecorationToPositiveOrientation(); /** * Sets the decoration type to arrows in negative plane direction. */ virtual void SetPlaneDecorationToNegativeOrientation(); using BaseProperty::operator=; protected: /** * Constructor. Sets the decoration type to none. */ PlaneOrientationProperty( ); /** * Constructor. Sets the decoration type to the given value. If it is not * valid, the interpolation is set to none */ PlaneOrientationProperty( const IdType &value ); /** * Constructor. Sets the decoration type to the given value. If it is not * valid, the representation is set to none */ PlaneOrientationProperty( const std::string &value ); /** * this function is overridden as protected, so that the user may not add * additional invalid types. */ virtual bool AddEnum( const std::string &name, const IdType &id ); /** * Adds the standard enumeration types with corresponding strings. */ virtual void AddDecorationTypes(); private: // purposely not implemented PlaneOrientationProperty(const PlaneOrientationProperty&); PlaneOrientationProperty& operator=(const PlaneOrientationProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkResliceMethodProperty.h b/Core/Code/DataManagement/mitkResliceMethodProperty.h index dff56b7d65..e54428135e 100644 --- a/Core/Code/DataManagement/mitkResliceMethodProperty.h +++ b/Core/Code/DataManagement/mitkResliceMethodProperty.h @@ -1,59 +1,68 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $ Version: $Revision: 14081 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __MITKRESLICEMETHODENUMPROPERTY_H #define __MITKRESLICEMETHODENUMPROPERTY_H #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the thick slices method enumeration */ class MITK_CORE_EXPORT ResliceMethodProperty : public EnumerationProperty { public: mitkClassMacro( ResliceMethodProperty, EnumerationProperty ); itkNewMacro(ResliceMethodProperty); mitkNewMacro1Param(ResliceMethodProperty, const IdType&); mitkNewMacro1Param(ResliceMethodProperty, const std::string&); using BaseProperty::operator=; protected: ResliceMethodProperty( ); ResliceMethodProperty( const IdType& value ); ResliceMethodProperty( const std::string& value ); void AddThickSlicesTypes(); private: // purposely not implemented ResliceMethodProperty(const ResliceMethodProperty&); ResliceMethodProperty& operator=(const ResliceMethodProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif //_MITK_VTK_SCALARMODE_PROPERTY__H_ diff --git a/Core/Code/DataManagement/mitkShaderProperty.h b/Core/Code/DataManagement/mitkShaderProperty.h index a62695895d..72f456c0a0 100644 --- a/Core/Code/DataManagement/mitkShaderProperty.h +++ b/Core/Code/DataManagement/mitkShaderProperty.h @@ -1,107 +1,116 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-04-14 19:45:53 +0200 (Mo, 14 Apr 2008) $ Version: $Revision: 14081 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __MITKSHADERENUMPROPERTY_H #define __MITKSHADERENUMPROPERTY_H #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the shader enumeration */ class MITK_CORE_EXPORT ShaderProperty : public EnumerationProperty { public: class Element { public: std::string name; }; mitkClassMacro( ShaderProperty, EnumerationProperty ); itkNewMacro(ShaderProperty); mitkNewMacro1Param(ShaderProperty, const IdType&); mitkNewMacro1Param(ShaderProperty, const std::string&); /** * Returns the current scalar mode value as defined by VTK constants. * @returns the current scalar mode as VTK constant. */ IdType GetShaderId(); std::string GetShaderName(); void SetShader(const IdType& i); void SetShader(const std::string& i); using BaseProperty::operator=; protected: std::list shaderList; /** * Constructor. Sets the representation to a default value of surface(2) */ ShaderProperty( ); /** * \brief Sets the scalar mode to the given value. If it is not * valid, the scalar mode is set to default (0). * @param value the integer representation of the scalar mode */ ShaderProperty( const IdType& value ); /** * \brief Sets the scalar mode to the given value. If it is not * valid, the representation is set to default (0). * @param value the string representation of the scalar mode */ ShaderProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid scalar mode types. */ bool AddEnum( const std::string& name, const IdType& id = 0); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ void AddShaderTypes(); private: // purposely not implemented ShaderProperty(const ShaderProperty&); ShaderProperty& operator=(const ShaderProperty&); virtual bool Assign(const BaseProperty &property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif //_MITK_VTK_SCALARMODE_PROPERTY__H_ diff --git a/Core/Code/DataManagement/mitkSmartPointerProperty.h b/Core/Code/DataManagement/mitkSmartPointerProperty.h index 900af29de5..d418a191eb 100644 --- a/Core/Code/DataManagement/mitkSmartPointerProperty.h +++ b/Core/Code/DataManagement/mitkSmartPointerProperty.h @@ -1,97 +1,106 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 #define MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 #include #include "mitkBaseProperty.h" #include "mitkUIDGenerator.h" #include #include #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + //##Documentation //## @brief Property containing a smart-pointer //## @ingroup DataManagement class MITK_CORE_EXPORT SmartPointerProperty : public BaseProperty { public: mitkClassMacro(SmartPointerProperty, BaseProperty); itkNewMacro(SmartPointerProperty); mitkNewMacro1Param(SmartPointerProperty, itk::Object*); typedef itk::Object::Pointer ValueType; itk::Object::Pointer GetSmartPointer() const; ValueType GetValue() const; void SetSmartPointer(itk::Object*); void SetValue(const ValueType&); /// mainly for XML output virtual std::string GetValueAsString() const; static void PostProcessXMLReading(); /// Return the number of SmartPointerProperties that reference the object given as parameter static unsigned int GetReferenceCountFor(itk::Object*); static std::string GetReferenceUIDFor(itk::Object*); static void RegisterPointerTarget(itk::Object*, const std::string uid); using BaseProperty::operator=; protected: SmartPointerProperty(itk::Object* = NULL); itk::Object::Pointer m_SmartPointer; private: // purposely not implemented SmartPointerProperty(const SmartPointerProperty&); SmartPointerProperty& operator=(const SmartPointerProperty&); virtual bool IsEqual(const BaseProperty&) const; virtual bool Assign(const BaseProperty&); typedef std::map ReferenceCountMapType; typedef std::map ReferencesUIDMapType; typedef std::map ReadInSmartPointersMapType; typedef std::map ReadInTargetsMapType; /// for each itk::Object* count how many SmartPointerProperties point to it static ReferenceCountMapType m_ReferenceCount; static ReferencesUIDMapType m_ReferencesUID; static ReadInSmartPointersMapType m_ReadInInstances; static ReadInTargetsMapType m_ReadInTargets; /// to generate unique IDs for the objects pointed at (during XML writing) static UIDGenerator m_UIDGenerator; }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKSMARTPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 */ diff --git a/Core/Code/DataManagement/mitkStringProperty.h b/Core/Code/DataManagement/mitkStringProperty.h index 5be7d3cc7a..55f4f14cd7 100644 --- a/Core/Code/DataManagement/mitkStringProperty.h +++ b/Core/Code/DataManagement/mitkStringProperty.h @@ -1,72 +1,81 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKSTRINGPROPERTY_H_HEADER_INCLUDED_C1C02491 #define MITKSTRINGPROPERTY_H_HEADER_INCLUDED_C1C02491 #include #include #include "mitkBaseProperty.h" #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * @brief Property for strings * @ingroup DataManagement */ class MITK_CORE_EXPORT StringProperty : public BaseProperty { protected: std::string m_Value; StringProperty( const char* string = 0 ); StringProperty( const std::string& s ); public: mitkClassMacro(StringProperty, BaseProperty); typedef std::string ValueType; itkNewMacro(StringProperty); mitkNewMacro1Param(StringProperty, const char*); mitkNewMacro1Param(StringProperty, const std::string&) itkGetStringMacro(Value); itkSetStringMacro(Value); virtual std::string GetValueAsString() const; static const char* PATH; using BaseProperty::operator=; private: // purposely not implemented StringProperty(const StringProperty&); StringProperty& operator=(const StringProperty&); virtual bool IsEqual(const BaseProperty& property ) const; virtual bool Assign(const BaseProperty& property ); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkTransferFunctionProperty.h b/Core/Code/DataManagement/mitkTransferFunctionProperty.h index 3645f3fc45..8b4d05c7e9 100644 --- a/Core/Code/DataManagement/mitkTransferFunctionProperty.h +++ b/Core/Code/DataManagement/mitkTransferFunctionProperty.h @@ -1,65 +1,74 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED #define MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED #include "mitkBaseProperty.h" #include "mitkTransferFunction.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + class MITK_CORE_EXPORT TransferFunctionProperty : public BaseProperty { public: typedef mitk::TransferFunction::Pointer ValueType; mitkClassMacro(TransferFunctionProperty, BaseProperty); itkNewMacro(TransferFunctionProperty); mitkNewMacro1Param(TransferFunctionProperty, mitk::TransferFunction::Pointer); itkSetMacro(Value, mitk::TransferFunction::Pointer ); itkGetConstMacro(Value, mitk::TransferFunction::Pointer ); std::string GetValueAsString() const; using BaseProperty::operator=; protected: mitk::TransferFunction::Pointer m_Value; TransferFunctionProperty(); TransferFunctionProperty( mitk::TransferFunction::Pointer value ); private: // purposely not implemented TransferFunctionProperty(const TransferFunctionProperty&); TransferFunctionProperty& operator=(const TransferFunctionProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKTRANFERFUNCTIONPROPERTY_H_HEADER_INCLUDED */ diff --git a/Core/Code/DataManagement/mitkVtkInterpolationProperty.h b/Core/Code/DataManagement/mitkVtkInterpolationProperty.h index 5929c200c6..40564bc993 100644 --- a/Core/Code/DataManagement/mitkVtkInterpolationProperty.h +++ b/Core/Code/DataManagement/mitkVtkInterpolationProperty.h @@ -1,111 +1,120 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_VTK_INTERPOLATION_PROPERTY__H_ #define _MITK_VTK_INTERPOLATION_PROPERTY__H_ #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the enumeration vtkInterpolation. Valid values are * (VTK constant/Id/string representation): * VTK_FLAT/0/Flat, VTK_GOURAUD/1/Gouraud, VTK_PHONG/2/Phong * Default is the Gouraud interpolation */ class MITK_CORE_EXPORT VtkInterpolationProperty : public EnumerationProperty { public: mitkClassMacro( VtkInterpolationProperty, EnumerationProperty ); itkNewMacro(VtkInterpolationProperty); mitkNewMacro1Param(VtkInterpolationProperty, const IdType&); mitkNewMacro1Param(VtkInterpolationProperty, const std::string&); /** * Returns the current interpolation value as defined by VTK constants. * @returns the current interpolation as VTK constant. */ virtual int GetVtkInterpolation(); /** * Sets the interpolation type to VTK_FLAT. */ virtual void SetInterpolationToFlat(); /** * Sets the interpolation type to VTK_WIREFRAME. */ virtual void SetInterpolationToGouraud(); /** * Sets the interpolation type to VTK_SURFACE. */ virtual void SetInterpolationToPhong(); using BaseProperty::operator=; protected: /** * Constructor. Sets the representation to a default value of surface(2) */ VtkInterpolationProperty( ); /** * Constructor. Sets the interpolation to the given value. If it is not * valid, the interpolation is set to gouraud(1) * @param value the integer representation of the interpolation */ VtkInterpolationProperty( const IdType& value ); /** * Constructor. Sets the interpolation to the given value. If it is not * valid, the representation is set to gouraud(1) * @param value the string representation of the interpolation */ VtkInterpolationProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid interpolation types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ virtual void AddInterpolationTypes(); private: // purposely not implemented VtkInterpolationProperty(const VtkInterpolationProperty&); VtkInterpolationProperty& operator=(const VtkInterpolationProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkVtkRepresentationProperty.h b/Core/Code/DataManagement/mitkVtkRepresentationProperty.h index 70a3a0bb9e..5798682cf6 100644 --- a/Core/Code/DataManagement/mitkVtkRepresentationProperty.h +++ b/Core/Code/DataManagement/mitkVtkRepresentationProperty.h @@ -1,109 +1,119 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_VTK_REPRESENTATION_PROPERTY__H_ #define _MITK_VTK_REPRESENTATION_PROPERTY__H_ #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the enumeration vtkRepresentation. Valid values are * (VTK constant/Id/string representation): * VTK_POINTS/0/Points, VTK_WIREFRAME/1/Wireframe, VTK_SURFACE/2/Surface * Default is the Surface representation */ class MITK_CORE_EXPORT VtkRepresentationProperty : public EnumerationProperty { public: mitkClassMacro( VtkRepresentationProperty, EnumerationProperty ); itkNewMacro(VtkRepresentationProperty); mitkNewMacro1Param(VtkRepresentationProperty, const IdType&); mitkNewMacro1Param(VtkRepresentationProperty, const std::string&); /** * Returns the current representation value as defined by VTK constants. * @returns the current representation as VTK constant. */ virtual int GetVtkRepresentation(); /** * Sets the representation type to VTK_POINTS. */ virtual void SetRepresentationToPoints(); /** * Sets the representation type to VTK_WIREFRAME. */ virtual void SetRepresentationToWireframe(); /** * Sets the representation type to VTK_SURFACE. */ virtual void SetRepresentationToSurface(); using BaseProperty::operator=; protected: /** * Constructor. Sets the representation to a default value of Surface(2) */ VtkRepresentationProperty( ); /** * Constructor. Sets the representation to the given value. If it is not * valid, the representation is set to Surface(2) * @param value the integer representation of the representation */ VtkRepresentationProperty( const IdType& value ); /** * Constructor. Sets the representation to the given value. If it is not * valid, the representation is set to Surface(2) * @param value the string representation of the representation */ VtkRepresentationProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid representation types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ virtual void AddRepresentationTypes(); private: // purposely not implemented VtkRepresentationProperty(const VtkRepresentationProperty&); VtkRepresentationProperty& operator=(const VtkRepresentationProperty&); }; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h index 28583e0c9d..b569917780 100644 --- a/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h +++ b/Core/Code/DataManagement/mitkVtkResliceInterpolationProperty.h @@ -1,107 +1,116 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_VTK_RESLICE_INTERPOLATION_PROPERTY__H_ #define _MITK_VTK_RESLICE_INTERPOLATION_PROPERTY__H_ #include "mitkEnumerationProperty.h" #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the enumeration for reslice interpolation. Valid values are * (VTK constant/Id/string representation): * VTK_RESLICE_NEAREST, VTK_RESLICE_LINEAR, VTK_RESLICE_CUBIC * Default is VTK_RESLICE_NEAREST */ class MITK_CORE_EXPORT VtkResliceInterpolationProperty : public EnumerationProperty { public: mitkClassMacro( VtkResliceInterpolationProperty, EnumerationProperty ); itkNewMacro(VtkResliceInterpolationProperty); mitkNewMacro1Param(VtkResliceInterpolationProperty, const IdType&); mitkNewMacro1Param(VtkResliceInterpolationProperty, const std::string&); /** * Returns the current interpolation value as defined by VTK constants. */ virtual int GetInterpolation(); /** * Sets the interpolation type to VTK_RESLICE_NEAREST. */ virtual void SetInterpolationToNearest(); /** * Sets the interpolation type to VTK_RESLICE_LINEAR. */ virtual void SetInterpolationToLinear(); /** * Sets the interpolation type to VTK_RESLICE_CUBIC. */ virtual void SetInterpolationToCubic(); using BaseProperty::operator=; protected: /** Sets reslice interpolation mode to default (VTK_RESLICE_NEAREST). */ VtkResliceInterpolationProperty( ); /** * Constructor. Sets reslice interpolation to the given value. */ VtkResliceInterpolationProperty( const IdType& value ); /** * Constructor. Sets reslice interpolation to the given value. */ VtkResliceInterpolationProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid interpolation types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ virtual void AddInterpolationTypes(); private: // purposely not implemented VtkResliceInterpolationProperty(const VtkResliceInterpolationProperty&); VtkResliceInterpolationProperty& operator=(const VtkResliceInterpolationProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkVtkScalarModeProperty.h b/Core/Code/DataManagement/mitkVtkScalarModeProperty.h index ad14415ca5..c0117dd11c 100644 --- a/Core/Code/DataManagement/mitkVtkScalarModeProperty.h +++ b/Core/Code/DataManagement/mitkVtkScalarModeProperty.h @@ -1,109 +1,118 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_VTK_SCALARMODE_PROPERTY__H_ #define _MITK_VTK_SCALARMODE_PROPERTY__H_ #include "mitkEnumerationProperty.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the enumeration vtkInterpolation. Valid values are * (VTK constant/Id/string representation): * \li VTK_SCALAR_MODE_DEFAULT/0/Default, * \li VTK_SCALAR_MODE_USE_POINT_DATA/1/PointData, * \li VTK_SCALAR_MODE_USE_CELL_DATA/2/CellData * \li VTK_SCALAR_MODE_USE_POINT_FIELD_DATA/3/PointFieldData * \li VTK_SCALAR_MODE_USE_CELL_FIELD_DATA/4/CellFieldData */ class MITK_CORE_EXPORT VtkScalarModeProperty : public EnumerationProperty { public: mitkClassMacro( VtkScalarModeProperty, EnumerationProperty ); itkNewMacro(VtkScalarModeProperty); mitkNewMacro1Param(VtkScalarModeProperty, const IdType&); mitkNewMacro1Param(VtkScalarModeProperty, const std::string&); /** * Returns the current scalar mode value as defined by VTK constants. * @returns the current scalar mode as VTK constant. */ virtual int GetVtkScalarMode(); virtual void SetScalarModeToDefault(); virtual void SetScalarModeToPointData(); virtual void SetScalarModeToCellData(); virtual void SetScalarModeToPointFieldData(); virtual void SetScalarModeToCellFieldData(); using BaseProperty::operator=; protected: /** * Constructor. Sets the representation to a default value of surface(2) */ VtkScalarModeProperty( ); /** * \brief Sets the scalar mode to the given value. If it is not * valid, the scalar mode is set to default (0). * @param value the integer representation of the scalar mode */ VtkScalarModeProperty( const IdType& value ); /** * \brief Sets the scalar mode to the given value. If it is not * valid, the representation is set to default (0). * @param value the string representation of the scalar mode */ VtkScalarModeProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid scalar mode types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ virtual void AddInterpolationTypes(); private: // purposely not implemented VtkScalarModeProperty(const VtkScalarModeProperty&); VtkScalarModeProperty& operator=(const VtkScalarModeProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif //_MITK_VTK_SCALARMODE_PROPERTY__H_ diff --git a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h index 7882fa37d0..467c2def5c 100644 --- a/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h +++ b/Core/Code/DataManagement/mitkVtkVolumeRenderingProperty.h @@ -1,103 +1,112 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_VTK_VOLUME_RENDERING_PROPERTY__H_ #define _MITK_VTK_VOLUME_RENDERING_PROPERTY__H_ #include "mitkEnumerationProperty.h" #define VTK_RAY_CAST_COMPOSITE_FUNCTION 1 #define VTK_VOLUME_RAY_CAST_MIP_FUNCTION 2 namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** * Encapsulates the enumeration for volume rendering. Valid values are * (VTK constant/Id/string representation): * VTK_VOLUME_RAY_CAST_MIP_FUNCTION * VTK_RAY_CAST_COMPOSITE_FUNCTION * Default is NULL */ class MITK_CORE_EXPORT VtkVolumeRenderingProperty : public EnumerationProperty { public: mitkClassMacro( VtkVolumeRenderingProperty, EnumerationProperty ); itkNewMacro(VtkVolumeRenderingProperty); mitkNewMacro1Param(VtkVolumeRenderingProperty, const IdType&); mitkNewMacro1Param(VtkVolumeRenderingProperty, const std::string&); /** * Returns the current volume rendering type */ virtual int GetRenderingType(); /** * Sets the rendering type to VTK_VOLUME_RAY_CAST_MIP_FUNCTION */ virtual void SetRenderingTypeToMIP(); /** * Sets the rendering type to VTK_RAY_CAST_COMPOSITE_FUNCTION */ virtual void SetRenderingTypeToComposite(); using BaseProperty::operator=; protected: /** Sets rendering type to default (VTK_RAY_CAST_COMPOSITE_FUNCTION). */ VtkVolumeRenderingProperty( ); /** * Constructor. Sets rendering type to the given value. */ VtkVolumeRenderingProperty( const IdType& value ); /** * Constructor. Sets rendering type to the given value. */ VtkVolumeRenderingProperty( const std::string& value ); /** * this function is overridden as protected, so that the user may not add * additional invalid rendering types. */ virtual bool AddEnum( const std::string& name, const IdType& id ); /** * Adds the enumeration types as defined by vtk to the list of known * enumeration values. */ virtual void AddRenderingTypes(); private: // purposely not implemented VtkVolumeRenderingProperty(const VtkVolumeRenderingProperty&); VtkVolumeRenderingProperty& operator=(const VtkVolumeRenderingProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // end of namespace mitk #endif diff --git a/Core/Code/DataManagement/mitkWeakPointerProperty.h b/Core/Code/DataManagement/mitkWeakPointerProperty.h index 453074b3e5..05b401db60 100644 --- a/Core/Code/DataManagement/mitkWeakPointerProperty.h +++ b/Core/Code/DataManagement/mitkWeakPointerProperty.h @@ -1,72 +1,81 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 #define MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 #include #include "mitkBaseProperty.h" #include "itkWeakPointer.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + //##Documentation //## @brief Property containing a smart-pointer //## //## @ingroup DataManagement class MITK_CORE_EXPORT WeakPointerProperty : public BaseProperty { public: mitkClassMacro(WeakPointerProperty, BaseProperty); itkNewMacro(WeakPointerProperty); mitkNewMacro1Param(WeakPointerProperty, itk::Object*); virtual ~WeakPointerProperty(); typedef itk::WeakPointer ValueType; ValueType GetWeakPointer() const; ValueType GetValue() const; void SetWeakPointer(itk::Object* pointer); void SetValue(const ValueType& value); virtual std::string GetValueAsString() const; using BaseProperty::operator=; protected: itk::WeakPointer m_WeakPointer; WeakPointerProperty(itk::Object* pointer = 0); private: // purposely not implemented WeakPointerProperty(const WeakPointerProperty&); WeakPointerProperty& operator=(const WeakPointerProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKWEAKPOINTERPROPERTY_H_HEADER_INCLUDED_C126B791 */ diff --git a/Core/Code/IO/mitkDicomSeriesReader.cpp b/Core/Code/IO/mitkDicomSeriesReader.cpp index e35e23aa6a..452a5af17a 100644 --- a/Core/Code/IO/mitkDicomSeriesReader.cpp +++ b/Core/Code/IO/mitkDicomSeriesReader.cpp @@ -1,1098 +1,1098 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // uncomment for learning more about the internal sorting mechanisms //#define MBILOG_ENABLE_DEBUG #include #include #include #include #include #include #include #include "mitkProperties.h" namespace mitk { typedef itk::GDCMSeriesFileNames DcmFileNamesGeneratorType; const DicomSeriesReader::TagToPropertyMapType& DicomSeriesReader::GetDICOMTagsToMITKPropertyMap() { static bool initialized = false; static TagToPropertyMapType dictionary; if (!initialized) { /* Selection criteria: - no sequences because we cannot represent that - nothing animal related (specied, breed registration number), MITK focusses on human medical image processing. - only general attributes so far When extending this, we should make use of a real dictionary (GDCM/DCMTK and lookup the tag names there) */ // Patient module dictionary["0010|0010"] = "dicom.patient.PatientsName"; dictionary["0010|0020"] = "dicom.patient.PatientID"; dictionary["0010|0030"] = "dicom.patient.PatientsBirthDate"; dictionary["0010|0040"] = "dicom.patient.PatientsSex"; dictionary["0010|0032"] = "dicom.patient.PatientsBirthTime"; dictionary["0010|1000"] = "dicom.patient.OtherPatientIDs"; dictionary["0010|1001"] = "dicom.patient.OtherPatientNames"; dictionary["0010|2160"] = "dicom.patient.EthnicGroup"; dictionary["0010|4000"] = "dicom.patient.PatientComments"; dictionary["0012|0062"] = "dicom.patient.PatientIdentityRemoved"; dictionary["0012|0063"] = "dicom.patient.DeIdentificationMethod"; // General Study module dictionary["0020|000d"] = "dicom.study.StudyInstanceUID"; dictionary["0008|0020"] = "dicom.study.StudyDate"; dictionary["0008|0030"] = "dicom.study.StudyTime"; dictionary["0008|0090"] = "dicom.study.ReferringPhysiciansName"; dictionary["0020|0010"] = "dicom.study.StudyID"; dictionary["0008|0050"] = "dicom.study.AccessionNumber"; dictionary["0008|1030"] = "dicom.study.StudyDescription"; dictionary["0008|1048"] = "dicom.study.PhysiciansOfRecord"; dictionary["0008|1060"] = "dicom.study.NameOfPhysicianReadingStudy"; // General Series module dictionary["0008|0060"] = "dicom.series.Modality"; dictionary["0020|000e"] = "dicom.series.SeriesInstanceUID"; dictionary["0020|0011"] = "dicom.series.SeriesNumber"; dictionary["0020|0060"] = "dicom.series.Laterality"; dictionary["0008|0021"] = "dicom.series.SeriesDate"; dictionary["0008|0031"] = "dicom.series.SeriesTime"; dictionary["0008|1050"] = "dicom.series.PerformingPhysiciansName"; dictionary["0018|1030"] = "dicom.series.ProtocolName"; dictionary["0008|103e"] = "dicom.series.SeriesDescription"; dictionary["0008|1070"] = "dicom.series.OperatorsName"; dictionary["0018|0015"] = "dicom.series.BodyPartExamined"; dictionary["0018|5100"] = "dicom.series.PatientPosition"; dictionary["0028|0108"] = "dicom.series.SmallestPixelValueInSeries"; dictionary["0028|0109"] = "dicom.series.LargestPixelValueInSeries"; // VOI LUT module dictionary["0028|1050"] = "dicom.voilut.WindowCenter"; dictionary["0028|1051"] = "dicom.voilut.WindowWidth"; dictionary["0028|1055"] = "dicom.voilut.WindowCenterAndWidthExplanation"; initialized = true; } return dictionary; } DataNode::Pointer DicomSeriesReader::LoadDicomSeries(const StringContainer &filenames, bool sort, bool check_4d, UpdateCallBackMethod callback) { DataNode::Pointer node = DataNode::New(); if (DicomSeriesReader::LoadDicomSeries(filenames, *node, sort, check_4d, callback)) { if( filenames.empty() ) { return NULL; } return node; } else { return NULL; } } bool DicomSeriesReader::LoadDicomSeries(const StringContainer &filenames, DataNode &node, bool sort, bool check_4d, UpdateCallBackMethod callback) { if( filenames.empty() ) { MITK_WARN << "Calling LoadDicomSeries with empty filename string container. Probably invalid application logic."; node.SetData(NULL); return true; // this is not actually an error but the result is very simple } DcmIoType::Pointer io = DcmIoType::New(); try { if (io->CanReadFile(filenames.front().c_str())) { io->SetFileName(filenames.front().c_str()); io->ReadImageInformation(); switch (io->GetComponentType()) { case DcmIoType::UCHAR: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::CHAR: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::USHORT: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::SHORT: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::UINT: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::INT: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::ULONG: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::LONG: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::FLOAT: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; case DcmIoType::DOUBLE: DicomSeriesReader::LoadDicom(filenames, node, sort, check_4d, callback); return true; default: MITK_ERROR << "Found unsupported DICOM pixel type: (enum value) " << io->GetComponentType(); } } } catch(itk::MemoryAllocationError& e) { MITK_ERROR << "Out of memory. Cannot load DICOM series: " << e.what(); } catch(std::exception& e) { MITK_ERROR << "Error encountered when loading DICOM series:" << e.what(); } catch(...) { MITK_ERROR << "Unspecified error encountered when loading DICOM series."; } return false; } bool DicomSeriesReader::IsDicom(const std::string &filename) { DcmIoType::Pointer io = DcmIoType::New(); return io->CanReadFile(filename.c_str()); } bool DicomSeriesReader::IsPhilips3DDicom(const std::string &filename) { DcmIoType::Pointer io = DcmIoType::New(); if (io->CanReadFile(filename.c_str())) { //Look at header Tag 3001,0010 if it is "Philips3D" gdcm::Reader reader; reader.SetFileName(filename.c_str()); reader.Read(); gdcm::DataSet &data_set = reader.GetFile().GetDataSet(); gdcm::StringFilter sf; sf.SetFile(reader.GetFile()); if (data_set.FindDataElement(gdcm::Tag(0x3001, 0x0010)) && (sf.ToString(gdcm::Tag(0x3001, 0x0010)) == "Philips3D ")) { return true; } } return false; } bool DicomSeriesReader::ReadPhilips3DDicom(const std::string &filename, mitk::Image::Pointer output_image) { // Now get PhilipsSpecific Tags gdcm::PixmapReader reader; reader.SetFileName(filename.c_str()); reader.Read(); gdcm::DataSet &data_set = reader.GetFile().GetDataSet(); gdcm::StringFilter sf; sf.SetFile(reader.GetFile()); gdcm::Attribute<0x0028,0x0011> dimTagX; // coloumns || sagittal gdcm::Attribute<0x3001,0x1001, gdcm::VR::UL, gdcm::VM::VM1> dimTagZ; //I have no idea what is VM1. // (Philips specific) // transversal gdcm::Attribute<0x0028,0x0010> dimTagY; // rows || coronal gdcm::Attribute<0x0028,0x0008> dimTagT; // how many frames gdcm::Attribute<0x0018,0x602c> spaceTagX; // Spacing in X , unit is "physicalTagx" (usually centimeter) gdcm::Attribute<0x0018,0x602e> spaceTagY; gdcm::Attribute<0x3001,0x1003, gdcm::VR::FD, gdcm::VM::VM1> spaceTagZ; // (Philips specific) gdcm::Attribute<0x0018,0x6024> physicalTagX; // if 3, then spacing params are centimeter gdcm::Attribute<0x0018,0x6026> physicalTagY; gdcm::Attribute<0x3001,0x1002, gdcm::VR::US, gdcm::VM::VM1> physicalTagZ; // (Philips specific) dimTagX.Set(data_set); dimTagY.Set(data_set); dimTagZ.Set(data_set); dimTagT.Set(data_set); spaceTagX.Set(data_set); spaceTagY.Set(data_set); spaceTagZ.Set(data_set); physicalTagX.Set(data_set); physicalTagY.Set(data_set); physicalTagZ.Set(data_set); unsigned int dimX = dimTagX.GetValue(), dimY = dimTagY.GetValue(), dimZ = dimTagZ.GetValue(), dimT = dimTagT.GetValue(), physicalX = physicalTagX.GetValue(), physicalY = physicalTagY.GetValue(), physicalZ = physicalTagZ.GetValue(); float spaceX = spaceTagX.GetValue(), spaceY = spaceTagY.GetValue(), spaceZ = spaceTagZ.GetValue(); if (physicalX == 3) // spacing parameter in cm, have to convert it to mm. spaceX = spaceX * 10; if (physicalY == 3) // spacing parameter in cm, have to convert it to mm. spaceY = spaceY * 10; if (physicalZ == 3) // spacing parameter in cm, have to convert it to mm. spaceZ = spaceZ * 10; // Ok, got all necessary Tags! // Now read Pixeldata (7fe0,0010) X x Y x Z x T Elements const gdcm::Pixmap &pixels = reader.GetPixmap(); gdcm::RAWCodec codec; codec.SetPhotometricInterpretation(gdcm::PhotometricInterpretation::MONOCHROME2); codec.SetPixelFormat(pixels.GetPixelFormat()); codec.SetPlanarConfiguration(0); gdcm::DataElement out; codec.Decode(data_set.GetDataElement(gdcm::Tag(0x7fe0, 0x0010)), out); const gdcm::ByteValue *bv = out.GetByteValue(); const char *new_pixels = bv->GetPointer(); // Create MITK Image + Geometry typedef itk::Image ImageType; //Pixeltype might be different sometimes? Maybe read it out from header ImageType::RegionType myRegion; ImageType::SizeType mySize; ImageType::IndexType myIndex; ImageType::SpacingType mySpacing; ImageType::Pointer imageItk = ImageType::New(); mySpacing[0] = spaceX; mySpacing[1] = spaceY; mySpacing[2] = spaceZ; mySpacing[3] = 1; myIndex[0] = 0; myIndex[1] = 0; myIndex[2] = 0; myIndex[3] = 0; mySize[0] = dimX; mySize[1] = dimY; mySize[2] = dimZ; mySize[3] = dimT; myRegion.SetSize( mySize); myRegion.SetIndex( myIndex ); imageItk->SetSpacing(mySpacing); imageItk->SetRegions( myRegion); imageItk->Allocate(); imageItk->FillBuffer(0); itk::ImageRegionIterator iterator(imageItk, imageItk->GetLargestPossibleRegion()); iterator.GoToBegin(); unsigned long pixCount = 0; unsigned long planeSize = dimX*dimY; unsigned long planeCount = 0; unsigned long timeCount = 0; unsigned long numberOfSlices = dimZ; while (!iterator.IsAtEnd()) { unsigned long adressedPixel = pixCount + (numberOfSlices-1-planeCount)*planeSize // add offset to adress the first pixel of current plane + timeCount*numberOfSlices*planeSize; // add time offset iterator.Set( new_pixels[ adressedPixel ] ); pixCount++; ++iterator; if (pixCount == planeSize) { pixCount = 0; planeCount++; } if (planeCount == numberOfSlices) { planeCount = 0; timeCount++; } if (timeCount == dimT) { break; } } mitk::CastToMitkImage(imageItk, output_image); return true; // actually never returns false yet.. but exception possible } DicomSeriesReader::TwoStringContainers DicomSeriesReader::AnalyzeFileForITKImageSeriesReaderSpacingAssumption( const StringContainer& files, const gdcm::Scanner::MappingType& tagValueMappings_) { // result.first = files that fit ITK's assumption // result.second = files that do not fit, should be run through AnalyzeFileForITKImageSeriesReaderSpacingAssumption() again TwoStringContainers result; // we const_cast here, because I could not use a map.at(), which would make the code much more readable gdcm::Scanner::MappingType& tagValueMappings = const_cast(tagValueMappings_); const gdcm::Tag tagImagePositionPatient(0x0020,0x0032); // Image Position (Patient) const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // Image Orientation Vector3D fromFirstToSecondOrigin; fromFirstToSecondOrigin.Fill(0.0); bool fromFirstToSecondOriginInitialized(false); Point3D thisOrigin; Point3D lastOrigin; Point3D lastDifferentOrigin; bool lastOriginInitialized(false); MITK_DEBUG << "--------------------------------------------------------------------------------"; MITK_DEBUG << "Analyzing files for z-spacing assumption of ITK's ImageSeriesReader "; unsigned int fileIndex(0); for (StringContainer::const_iterator fileIter = files.begin(); fileIter != files.end(); ++fileIter, ++fileIndex) { bool fileFitsIntoPattern(false); std::string thisOriginString; // Read tag value into point3D. PLEASE replace this by appropriate GDCM code if you figure out how to do that const char* value = tagValueMappings[fileIter->c_str()][tagImagePositionPatient]; if (value) { thisOriginString = value; } std::istringstream originReader(thisOriginString); std::string coordinate; unsigned int dim(0); while( std::getline( originReader, coordinate, '\\' ) ) thisOrigin[dim++] = atof(coordinate.c_str()); if (dim != 3) { MITK_ERROR << "Reader implementation made wrong assumption on tag (0020,0032). Found " << dim << "instead of 3 values."; } MITK_DEBUG << " " << fileIndex << " " << *fileIter << " at " << thisOriginString << "(" << thisOrigin[0] << "," << thisOrigin[1] << "," << thisOrigin[2] << ")"; if ( lastOriginInitialized && (thisOrigin == lastOrigin) ) { MITK_DEBUG << " ==> Sort away " << *fileIter << " for separate time step"; // we already have one occupying this position result.second.push_back( *fileIter ); fileFitsIntoPattern = false; } else { if (!fromFirstToSecondOriginInitialized && lastOriginInitialized) // calculate vector as soon as possible when we get a new position { fromFirstToSecondOrigin = thisOrigin - lastDifferentOrigin; fromFirstToSecondOriginInitialized = true; // Now make sure this direction is along the normal vector of the first slice // If this is NOT the case, then we have a data set with a TILTED GANTRY geometry, // which cannot be loaded into a single mitk::Image at the moment // Again ugly code to read tag Image Orientation into two vEctors Vector3D right; right.Fill(0.0); Vector3D up; right.Fill(0.0); // might be down as well, but it is just a name at this point std::string thisOrientationString; const char* value = tagValueMappings[fileIter->c_str()][tagImageOrientation]; if (value) { thisOrientationString = value; } std::istringstream orientationReader(thisOrientationString); std::string coordinate; unsigned int dim(0); while( std::getline( orientationReader, coordinate, '\\' ) ) if (dim<3) right[dim++] = atof(coordinate.c_str()); else up[dim++ - 3] = atof(coordinate.c_str()); if (dim != 6) { MITK_ERROR << "Reader implementation made wrong assumption on tag (0020,0037). Found " << dim << "instead of 6 values."; } /* Determine if line (thisOrigin + l * normal) contains lastDifferentOrigin. Done by calculating the distance of lastDifferentOrigin from line (thisOrigin + l *normal) E.g. http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html squared distance = | (pointAlongNormal - thisOrign) x (thisOrigin - lastDifferentOrigin) | ^ 2 / |pointAlongNormal - thisOrigin| ^ 2 ( x meaning the cross product ) MITK_DEBUG << "Tilt check: right vector (" << right[0] << "," << right[1] << "," << right[2] << "), " "up vector (" << up[0] << "," << up[1] << "," << up[2] << ")"; */ Vector3D normal = itk::CrossProduct(right, up); Point3D pointAlongNormal = thisOrigin + normal; double numerator = itk::CrossProduct( pointAlongNormal - thisOrigin , thisOrigin - lastDifferentOrigin ).GetSquaredNorm(); double denominator = (pointAlongNormal - thisOrigin).GetSquaredNorm(); double distance = sqrt(numerator / denominator); if (distance > 0.001) // mitk::eps is too small; 1/1000 of a mm should be enough to detect tilt { MITK_DEBUG << " Series might contain a tilted geometry"; MITK_DEBUG << " Distance of expected slice origin from actual slice origin: " << distance; MITK_DEBUG << " ==> Sort away " << *fileIter << " for later analysis"; /* Pessimistic approach: split block right here result.first.assign( files.begin(), fileIter ); result.second.insert( result.second.end(), fileIter, files.end() ); return result; // stop processing with first split */ /* optimistic approach: save file for later, check all further files */ result.second.push_back(*fileIter); fileFitsIntoPattern = false; } else { result.first.push_back(*fileIter); // this file is good for current block fileFitsIntoPattern = true; } } else if (fromFirstToSecondOriginInitialized) // we already know the offset between slices { Point3D assumedOrigin = lastDifferentOrigin + fromFirstToSecondOrigin; Vector3D originError = assumedOrigin - thisOrigin; double norm = originError.GetNorm(); double toleratedError(0.005); // max. 1/10mm error when measurement crosses 20 slices in z direction if (norm > toleratedError) { MITK_DEBUG << " File does not fit into the inter-slice distance pattern (diff = " << norm << ", allowed " << toleratedError << ")."; MITK_DEBUG << " Expected position (" << assumedOrigin[0] << "," << assumedOrigin[1] << "," << assumedOrigin[2] << "), got position (" << thisOrigin[0] << "," << thisOrigin[1] << "," << thisOrigin[2] << ")"; MITK_DEBUG << " ==> Sort away " << *fileIter << " for later analysis"; // At this point we know we deviated from the expectation of ITK's ImageSeriesReader // We split the input file list at this point, i.e. all files up to this one (excluding it) // are returned as group 1, the remaining files (including the faulty one) are group 2 /* Pessimistic approach: split right here: result.first.assign( files.begin(), fileIter ); result.second.insert( result.second.end(), fileIter, files.end() ); return result; // stop processing with first split */ /* Optimistic approach: check if any of the remaining slices fits in */ result.second.push_back( *fileIter ); // sort away for further analysis fileFitsIntoPattern = false; } else { result.first.push_back(*fileIter); // this file is good for current block fileFitsIntoPattern = true; } } else // this should be the very first slice { result.first.push_back(*fileIter); // this file is good for current block fileFitsIntoPattern = true; } } // recored current origin for reference in later iterations if ( !lastOriginInitialized || ( fileFitsIntoPattern && (thisOrigin != lastOrigin) ) ) { lastDifferentOrigin = thisOrigin; } lastOrigin = thisOrigin; lastOriginInitialized = true; } return result; } DicomSeriesReader::UidFileNamesMap DicomSeriesReader::GetSeries(const StringContainer& files, const StringContainer &restrictions) { return GetSeries(files, true, restrictions); } DicomSeriesReader::UidFileNamesMap DicomSeriesReader::GetSeries(const StringContainer& files, bool sortTo3DPlust, const StringContainer& /*restrictions*/) { /** assumption about this method: returns a map of uid-like-key --> list(filename) each entry should contain filenames that have images of same - series instance uid (automatically done by GDCMSeriesFileNames - 0020,0037 image orientation (patient) - 0028,0030 pixel spacing (x,y) - 0018,0050 slice thickness */ UidFileNamesMap groupsOfSimilarImages; // preliminary result, refined into the final result mapOf3DPlusTBlocks // use GDCM directly, itk::GDCMSeriesFileNames does not work with GDCM 2 // PART I: scan files for sorting relevant DICOM tags, // separate images that differ in any of those // attributes (they cannot possibly form a 3D block) // scan for relevant tags in dicom files gdcm::Scanner scanner; const gdcm::Tag tagSeriesInstanceUID(0x0020,0x000e); // Series Instance UID scanner.AddTag( tagSeriesInstanceUID ); const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // image orientation scanner.AddTag( tagImageOrientation ); const gdcm::Tag tagPixelSpacing(0x0028, 0x0030); // pixel spacing scanner.AddTag( tagPixelSpacing ); const gdcm::Tag tagSliceThickness(0x0018, 0x0050); // slice thickness scanner.AddTag( tagSliceThickness ); const gdcm::Tag tagNumberOfRows(0x0028, 0x0010); // number rows scanner.AddTag( tagNumberOfRows ); const gdcm::Tag tagNumberOfColumns(0x0028, 0x0011); // number cols scanner.AddTag( tagNumberOfColumns ); // additional tags read in this scan to allow later analysis // THESE tag are not used for initial separating of files const gdcm::Tag tagImagePositionPatient(0x0020,0x0032); // Image Position (Patient) scanner.AddTag( tagImagePositionPatient ); // TODO add further restrictions from arguments // let GDCM scan files if ( !scanner.Scan( files ) ) { MITK_ERROR << "gdcm::Scanner failed when scanning " << files.size() << " input files."; return groupsOfSimilarImages; } // assign files IDs that will separate them for loading into image blocks for (gdcm::Scanner::ConstIterator fileIter = scanner.Begin(); fileIter != scanner.End(); ++fileIter) { //MITK_DEBUG << "Scan file " << fileIter->first << std::endl; if ( std::string(fileIter->first).empty() ) continue; // TODO understand why Scanner has empty string entries // we const_cast here, because I could not use a map.at() function in CreateMoreUniqueSeriesIdentifier. // doing the same thing with find would make the code less readable. Since we forget the Scanner results // anyway after this function, we can simply tolerate empty map entries introduced by bad operator[] access std::string moreUniqueSeriesId = CreateMoreUniqueSeriesIdentifier( const_cast(fileIter->second) ); groupsOfSimilarImages [ moreUniqueSeriesId ].push_back( fileIter->first ); } // PART III: sort slices spatially for ( UidFileNamesMap::const_iterator groupIter = groupsOfSimilarImages.begin(); groupIter != groupsOfSimilarImages.end(); ++groupIter ) { try { groupsOfSimilarImages[ groupIter->first ] = SortSeriesSlices( groupIter->second ); // sort each slice group spatially } catch(...) { MITK_ERROR << "Catched something."; } } // PART II: analyze pre-sorted images for valid blocks (i.e. blocks of equal z-spacing), // separate into multiple blocks if necessary. // // Analysis performs the following steps: // * imitate itk::ImageSeriesReader: use the distance between the first two images as z-spacing // * check what images actually fulfill ITK's z-spacing assumption // * separate all images that fail the test into new blocks, re-iterate analysis for these blocks UidFileNamesMap mapOf3DPlusTBlocks; // final result of this function for ( UidFileNamesMap::const_iterator groupIter = groupsOfSimilarImages.begin(); groupIter != groupsOfSimilarImages.end(); ++groupIter ) { UidFileNamesMap mapOf3DBlocks; // intermediate result for only this group(!) StringContainer filesStillToAnalyze = groupIter->second; std::string groupUID = groupIter->first; unsigned int subgroup(0); MITK_DEBUG << "Analyze group " << groupUID; while (!filesStillToAnalyze.empty()) // repeat until all files are grouped somehow { TwoStringContainers analysisResult = AnalyzeFileForITKImageSeriesReaderSpacingAssumption( filesStillToAnalyze, scanner.GetMappings() ); // enhance the UID for additional groups std::stringstream newGroupUID; newGroupUID << groupUID << '.' << subgroup; mapOf3DBlocks[ newGroupUID.str() ] = analysisResult.first; MITK_DEBUG << "Result: sorted 3D group " << newGroupUID.str() << " with " << mapOf3DBlocks[ newGroupUID.str() ].size() << " files"; ++subgroup; filesStillToAnalyze = analysisResult.second; // remember what needs further analysis } // end of grouping, now post-process groups // PART IV: attempt to group blocks to 3D+t blocks if requested // inspect entries of mapOf3DBlocks // - if number of files is identical to previous entry, collect for 3D+t block // - as soon as number of files changes from previous entry, record collected blocks as 3D+t block, start a new one, continue // decide whether or not to group 3D blocks into 3D+t blocks where possible if ( !sortTo3DPlust ) { // copy 3D blocks to output // TODO avoid collisions (or prove impossibility) mapOf3DPlusTBlocks.insert( mapOf3DBlocks.begin(), mapOf3DBlocks.end() ); } else { // sort 3D+t (as described in "PART IV") MITK_DEBUG << "================================================================================"; MITK_DEBUG << "3D+t analysis:"; unsigned int numberOfFilesInPreviousBlock(0); std::string previousBlockKey; for ( UidFileNamesMap::const_iterator block3DIter = mapOf3DBlocks.begin(); block3DIter != mapOf3DBlocks.end(); ++block3DIter ) { unsigned int numberOfFilesInThisBlock = block3DIter->second.size(); std::string thisBlockKey = block3DIter->first; if (numberOfFilesInPreviousBlock == 0) { numberOfFilesInPreviousBlock = numberOfFilesInThisBlock; mapOf3DPlusTBlocks[thisBlockKey].insert( mapOf3DPlusTBlocks[thisBlockKey].end(), block3DIter->second.begin(), block3DIter->second.end() ); MITK_DEBUG << " 3D+t group " << thisBlockKey << " started"; previousBlockKey = thisBlockKey; } else { bool identicalOrigins; try { // check whether this and the previous block share a comon origin // TODO should be safe, but a little try/catch or other error handling wouldn't hurt std::string thisOriginString = scanner.GetValue( mapOf3DBlocks[thisBlockKey].front().c_str(), tagImagePositionPatient ); std::string previousOriginString = scanner.GetValue( mapOf3DBlocks[previousBlockKey].front().c_str(), tagImagePositionPatient ); // also compare last origin, because this might differ if z-spacing is different std::string thisDestinationString = scanner.GetValue( mapOf3DBlocks[thisBlockKey].back().c_str(), tagImagePositionPatient ); std::string previousDestinationString = scanner.GetValue( mapOf3DBlocks[previousBlockKey].back().c_str(), tagImagePositionPatient ); identicalOrigins = ( (thisOriginString == previousOriginString) && (thisDestinationString == previousDestinationString) ); } catch(...) { identicalOrigins = false; } if (identicalOrigins && (numberOfFilesInPreviousBlock == numberOfFilesInThisBlock)) { // group with previous block mapOf3DPlusTBlocks[previousBlockKey].insert( mapOf3DPlusTBlocks[previousBlockKey].end(), block3DIter->second.begin(), block3DIter->second.end() ); MITK_DEBUG << " --> group enhanced with another timestep"; } else { // start a new block mapOf3DPlusTBlocks[thisBlockKey].insert( mapOf3DPlusTBlocks[thisBlockKey].end(), block3DIter->second.begin(), block3DIter->second.end() ); MITK_DEBUG << " ==> group closed with " << mapOf3DPlusTBlocks[previousBlockKey].size() / numberOfFilesInPreviousBlock << " time steps"; previousBlockKey = thisBlockKey; MITK_DEBUG << " 3D+t group " << thisBlockKey << " started"; } } numberOfFilesInPreviousBlock = numberOfFilesInThisBlock; } } } MITK_DEBUG << "================================================================================"; MITK_DEBUG << "Summary: "; for ( UidFileNamesMap::const_iterator groupIter = mapOf3DPlusTBlocks.begin(); groupIter != mapOf3DPlusTBlocks.end(); ++groupIter ) { MITK_DEBUG << " Image volume " << groupIter->first << " with " << groupIter->second.size() << " files"; } MITK_DEBUG << "Done. "; MITK_DEBUG << "================================================================================"; return mapOf3DPlusTBlocks; } DicomSeriesReader::UidFileNamesMap DicomSeriesReader::GetSeries(const std::string &dir, const StringContainer &restrictions) { gdcm::Directory directoryLister; directoryLister.Load( dir.c_str(), false ); // non-recursive return GetSeries(directoryLister.GetFilenames(), restrictions); } std::string DicomSeriesReader::CreateSeriesIdentifierPart( gdcm::Scanner::TagToValue& tagValueMap, const gdcm::Tag& tag ) { std::string result; try { result = IDifyTagValue( tagValueMap[ tag ] ? tagValueMap[ tag ] : std::string("") ); } catch (std::exception& e) { MITK_WARN << "Could not access tag " << tag << ": " << e.what(); } return result; } std::string DicomSeriesReader::CreateMoreUniqueSeriesIdentifier( gdcm::Scanner::TagToValue& tagValueMap ) { const gdcm::Tag tagSeriesInstanceUID(0x0020,0x000e); // Series Instance UID const gdcm::Tag tagImageOrientation(0x0020, 0x0037); // image orientation const gdcm::Tag tagPixelSpacing(0x0028, 0x0030); // pixel spacing const gdcm::Tag tagSliceThickness(0x0018, 0x0050); // slice thickness const gdcm::Tag tagNumberOfRows(0x0028, 0x0010); // number rows const gdcm::Tag tagNumberOfColumns(0x0028, 0x0011); // number cols std::string constructedID; try { constructedID = tagValueMap[ tagSeriesInstanceUID ]; } catch (std::exception& e) { MITK_ERROR << "CreateMoreUniqueSeriesIdentifier() could not access series instance UID. Something is seriously wrong with this image."; MITK_ERROR << "Error from exception: " << e.what(); } constructedID += CreateSeriesIdentifierPart( tagValueMap, tagNumberOfRows ); constructedID += CreateSeriesIdentifierPart( tagValueMap, tagNumberOfColumns ); constructedID += CreateSeriesIdentifierPart( tagValueMap, tagPixelSpacing ); constructedID += CreateSeriesIdentifierPart( tagValueMap, tagSliceThickness ); constructedID += CreateSeriesIdentifierPart( tagValueMap, tagImageOrientation ); constructedID.resize( constructedID.length() - 1 ); // cut of trailing '.' return constructedID; } std::string DicomSeriesReader::IDifyTagValue(const std::string& value) { std::string IDifiedValue( value ); if (value.empty()) throw std::logic_error("IDifyTagValue() illegaly called with empty tag value"); // Eliminate non-alnum characters, including whitespace... // that may have been introduced by concats. for(std::size_t i=0; i= 'a' && IDifiedValue[i] <= 'z') || (IDifiedValue[i] >= '0' && IDifiedValue[i] <= '9') || (IDifiedValue[i] >= 'A' && IDifiedValue[i] <= 'Z'))) { IDifiedValue.erase(i, 1); } } IDifiedValue += "."; return IDifiedValue; } DicomSeriesReader::StringContainer DicomSeriesReader::GetSeries(const std::string &dir, const std::string &series_uid, const StringContainer &restrictions) { UidFileNamesMap allSeries = GetSeries(dir, restrictions); StringContainer resultingFileList; for ( UidFileNamesMap::const_iterator idIter = allSeries.begin(); idIter != allSeries.end(); ++idIter ) { if ( idIter->first.find( series_uid ) == 0 ) // this ID starts with given series_uid { resultingFileList.insert( resultingFileList.end(), idIter->second.begin(), idIter->second.end() ); // append } } return resultingFileList; } DicomSeriesReader::StringContainer DicomSeriesReader::SortSeriesSlices(const StringContainer &unsortedFilenames) { gdcm::Sorter sorter; sorter.SetSortFunction(DicomSeriesReader::GdcmSortFunction); try { sorter.Sort(unsortedFilenames); return sorter.GetFilenames(); } - catch(std::logic_error& e) + catch(std::logic_error&) { MITK_WARN << "Sorting error. Leaving series unsorted."; return unsortedFilenames; } } bool DicomSeriesReader::GdcmSortFunction(const gdcm::DataSet &ds1, const gdcm::DataSet &ds2) { // make sure we habe Image Position and Orientation if ( ! ( ds1.FindDataElement(gdcm::Tag(0x0020,0x0032)) && ds1.FindDataElement(gdcm::Tag(0x0020,0x0037)) && ds2.FindDataElement(gdcm::Tag(0x0020,0x0032)) && ds2.FindDataElement(gdcm::Tag(0x0020,0x0037)) ) ) { MITK_WARN << "Dicom images are missing attributes for a meaningful sorting."; throw std::logic_error("Dicom images are missing attributes for a meaningful sorting."); } gdcm::Attribute<0x0020,0x0032> image_pos1; // Image Position (Patient) gdcm::Attribute<0x0020,0x0037> image_orientation1; // Image Orientation (Patient) image_pos1.Set(ds1); image_orientation1.Set(ds1); gdcm::Attribute<0x0020,0x0032> image_pos2; gdcm::Attribute<0x0020,0x0037> image_orientation2; image_pos2.Set(ds2); image_orientation2.Set(ds2); if (image_orientation1 != image_orientation2) { MITK_ERROR << "Dicom images have different orientations."; throw std::logic_error("Dicom images have different orientations. Call GetSeries() first to separate images."); } double normal[3]; normal[0] = image_orientation1[1] * image_orientation1[5] - image_orientation1[2] * image_orientation1[4]; normal[1] = image_orientation1[2] * image_orientation1[3] - image_orientation1[0] * image_orientation1[5]; normal[2] = image_orientation1[0] * image_orientation1[4] - image_orientation1[1] * image_orientation1[3]; double dist1 = 0.0, dist2 = 0.0; for (unsigned char i = 0u; i < 3u; ++i) { dist1 += normal[i] * image_pos1[i]; dist2 += normal[i] * image_pos2[i]; } if ( fabs(dist1 - dist2) < mitk::eps) { gdcm::Attribute<0x0008,0x0032> acq_time1; // Acquisition time (may be missing, so we check existence first) gdcm::Attribute<0x0008,0x0032> acq_time2; if (ds1.FindDataElement(gdcm::Tag(0x0008,0x0032))) acq_time1.Set(ds1); if (ds2.FindDataElement(gdcm::Tag(0x0008,0x0032))) acq_time2.Set(ds2); // TODO this could lead to comparison of unset times (does Attribute initialize to good defaults?) // exception: same position: compare by acquisition time return acq_time1 < acq_time2; } else { // default: compare position return dist1 < dist2; } } std::string DicomSeriesReader::GetConfigurationString() { std::stringstream configuration; configuration << "MITK_USE_GDCMIO: "; configuration << "true"; configuration << "\n"; configuration << "GDCM_VERSION: "; #ifdef GDCM_MAJOR_VERSION configuration << GDCM_VERSION; #endif //configuration << "\n"; return configuration.str(); } void DicomSeriesReader::CopyMetaDataToImageProperties(StringContainer filenames, const gdcm::Scanner::MappingType &tagValueMappings_, DcmIoType *io, Image *image) { std::list imageBlock; imageBlock.push_back(filenames); CopyMetaDataToImageProperties(imageBlock, tagValueMappings_, io, image); } void DicomSeriesReader::CopyMetaDataToImageProperties( std::list imageBlock, const gdcm::Scanner::MappingType& tagValueMappings_, DcmIoType* io, Image* image) { if (!io || !image) return; StringLookupTable filesForSlices; StringLookupTable sliceLocationForSlices; StringLookupTable instanceNumberForSlices; StringLookupTable SOPInstanceNumberForSlices; gdcm::Scanner::MappingType& tagValueMappings = const_cast(tagValueMappings_); //DICOM tags which should be added to the image properties const gdcm::Tag tagSliceLocation(0x0020, 0x1041); // slice location const gdcm::Tag tagInstanceNumber(0x0020, 0x0013); // (image) instance number const gdcm::Tag tagSOPInstanceNumber(0x0008, 0x0018); // SOP instance number unsigned int timeStep(0); std::string propertyKeySliceLocation = "dicom.image.0020.1041"; std::string propertyKeyInstanceNumber = "dicom.image.0020.0013"; std::string propertyKeySOPInstanceNumber = "dicom.image.0008.0018"; // tags for each image for ( std::list::iterator i = imageBlock.begin(); i != imageBlock.end(); i++, timeStep++ ) { const StringContainer& files = (*i); unsigned int slice(0); for ( StringContainer::const_iterator fIter = files.begin(); fIter != files.end(); ++fIter, ++slice ) { filesForSlices.SetTableValue( slice, *fIter ); gdcm::Scanner::TagToValue tagValueMapForFile = tagValueMappings[fIter->c_str()]; if(tagValueMapForFile.find(tagSliceLocation) != tagValueMapForFile.end()) sliceLocationForSlices.SetTableValue(slice, tagValueMapForFile[tagSliceLocation]); if(tagValueMapForFile.find(tagInstanceNumber) != tagValueMapForFile.end()) instanceNumberForSlices.SetTableValue(slice, tagValueMapForFile[tagInstanceNumber]); if(tagValueMapForFile.find(tagSOPInstanceNumber) != tagValueMapForFile.end()) SOPInstanceNumberForSlices.SetTableValue(slice, tagValueMapForFile[tagSOPInstanceNumber]); } image->SetProperty( "files", StringLookupTableProperty::New( filesForSlices ) ); //If more than one time step add postfix ".t" + timestep if(timeStep != 0) { propertyKeySliceLocation.append(".t" + timeStep); propertyKeyInstanceNumber.append(".t" + timeStep); propertyKeySOPInstanceNumber.append(".t" + timeStep); } image->SetProperty( propertyKeySliceLocation.c_str(), StringLookupTableProperty::New( sliceLocationForSlices ) ); image->SetProperty( propertyKeyInstanceNumber.c_str(), StringLookupTableProperty::New( instanceNumberForSlices ) ); image->SetProperty( propertyKeySOPInstanceNumber.c_str(), StringLookupTableProperty::New( SOPInstanceNumberForSlices ) ); } // Copy tags for series, study, patient level (leave interpretation to application). // These properties will be copied to the DataNode by DicomSeriesReader. // tags for the series (we just use the one that ITK copied to its dictionary (proably that of the last slice) const itk::MetaDataDictionary& dict = io->GetMetaDataDictionary(); const TagToPropertyMapType& propertyLookup = DicomSeriesReader::GetDICOMTagsToMITKPropertyMap(); itk::MetaDataDictionary::ConstIterator dictIter = dict.Begin(); while ( dictIter != dict.End() ) { MITK_DEBUG << "Key " << dictIter->first; std::string value; if ( itk::ExposeMetaData( dict, dictIter->first, value ) ) { MITK_DEBUG << "Value " << value; TagToPropertyMapType::const_iterator valuePosition = propertyLookup.find( dictIter->first ); if ( valuePosition != propertyLookup.end() ) { std::string propertyKey = valuePosition->second; MITK_DEBUG << "--> " << propertyKey; image->SetProperty( propertyKey.c_str(), StringProperty::New(value) ); } } else { MITK_WARN << "Tag " << dictIter->first << " not read as string as expected. Ignoring..." ; } ++dictIter; } } } // end namespace mitk #include diff --git a/Core/Code/IO/mitkLookupTableProperty.h b/Core/Code/IO/mitkLookupTableProperty.h index a76223083c..e843c4437f 100755 --- a/Core/Code/IO/mitkLookupTableProperty.h +++ b/Core/Code/IO/mitkLookupTableProperty.h @@ -1,76 +1,85 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8 #define MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8 #include #include "mitkBaseProperty.h" #include "mitkLookupTable.h" namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + //##Documentation //## @brief Property for LookupTable data //## //## @ingroup DataManagement class MITK_CORE_EXPORT LookupTableProperty : public BaseProperty { protected: LookupTable::Pointer m_LookupTable; LookupTableProperty(); LookupTableProperty(const mitk::LookupTable::Pointer lut); public: typedef LookupTable::Pointer ValueType; mitkClassMacro(LookupTableProperty, BaseProperty); itkNewMacro(LookupTableProperty); mitkNewMacro1Param(LookupTableProperty, const mitk::LookupTable::Pointer); itkGetObjectMacro(LookupTable, LookupTable ); ValueType GetValue() const; void SetLookupTable(const mitk::LookupTable::Pointer aLookupTable); void SetValue(const ValueType&); virtual std::string GetValueAsString() const; using BaseProperty::operator=; private: // purposely not implemented LookupTableProperty(const LookupTableProperty&); LookupTableProperty& operator=(const LookupTableProperty&); virtual bool IsEqual(const BaseProperty& property) const; virtual bool Assign(const BaseProperty& property); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace mitk #endif /* MITKLookupTablePROPERTY_H_HEADER_INCLUDED_C10EEAA8 */ diff --git a/Core/Code/IO/mitkOperation.h b/Core/Code/IO/mitkOperation.h index a8c085e34d..5a4492aa2f 100644 --- a/Core/Code/IO/mitkOperation.h +++ b/Core/Code/IO/mitkOperation.h @@ -1,70 +1,68 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef OPERATION_H_HEADER_INCLUDED_C16E7D9E #define OPERATION_H_HEADER_INCLUDED_C16E7D9E #include -#pragma GCC visibility push(default) #include -#pragma GCC visibility pop namespace mitk { typedef int OperationType ; //##Documentation //## @brief Base class of all Operation-classes //## //## @ingroup Undo class MITK_CORE_EXPORT Operation { public: //##Documentation //## Constructor Operation(OperationType operationType); virtual ~Operation(); OperationType GetOperationType(); protected: OperationType m_OperationType; }; class MITK_CORE_EXPORT OperationEndEvent : public itk::EndEvent { public: typedef OperationEndEvent Self; typedef itk::EndEvent Superclass; OperationEndEvent(Operation* operation = NULL) : m_Operation(operation) {} virtual ~OperationEndEvent() {} virtual const char * GetEventName() const { return "OperationEndEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_Operation); } Operation* GetOperation() const { return m_Operation; } private: Operation* m_Operation; OperationEndEvent(const Self&); void operator=(const Self&); }; }//namespace mitk #endif /* OPERATION_H_HEADER_INCLUDED_C16E7D9E */ diff --git a/Core/Code/Service/mitkModule.h b/Core/Code/Service/mitkModule.h index dbbe618451..201cce375d 100644 --- a/Core/Code/Service/mitkModule.h +++ b/Core/Code/Service/mitkModule.h @@ -1,242 +1,242 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKMODULE_H #define MITKMODULE_H #include "mitkModuleVersion.h" namespace mitk { class CoreModuleContext; -class ModuleInfo; +struct ModuleInfo; class ModuleContext; class ModulePrivate; /** * \ingroup MicroServices * * Represents a MITK module. * *

* A %Module object is the access point to a MITK module. * Each MITK module has an associated %Module object. * *

* A module has unique identity, a long, chosen by the * framework. This identity does not change during the lifecycle of a module. * *

* A module can be in one of two states: *

    *
  • LOADED *
  • UNLOADED *
*

* You can determine the current state by using IsLoaded(). * *

* A module can only execute code when its state is LOADED. * An UNLOADED module is a * zombie and can only be reached because it was loaded before. However, * unloaded modules can be loaded again. * *

* The framework is the only entity that is allowed to create * %Module objects. * * @remarks This class is thread safe. */ class MITK_CORE_EXPORT Module { public: static const std::string& PROP_ID(); static const std::string& PROP_NAME(); static const std::string& PROP_LOCATION(); static const std::string& PROP_MODULE_DEPENDS(); static const std::string& PROP_PACKAGE_DEPENDS(); static const std::string& PROP_LIB_DEPENDS(); static const std::string& PROP_VERSION(); static const std::string& PROP_QT(); ~Module(); /** * Returns this module's current state. * *

* A module can be in only one state at any time. * * @return true if the module is LOADED * false if it is UNLOADED */ bool IsLoaded() const; /** * Returns this module's {@link ModuleContext}. The returned * ModuleContext can be used by the caller to act on behalf * of this module. * *

* If this module is not in the LOADED state, then this * module has no valid ModuleContext. This method will * return 0 if this module has no valid * ModuleContext. * * @return A ModuleContext for this module or * 0 if this module has no valid * ModuleContext. */ ModuleContext* GetModuleContext() const; /** * Returns this module's unique identifier. This module is assigned a unique * identifier by the framework when it was loaded. * *

* A module's unique identifier has the following attributes: *

    *
  • Is unique and persistent. *
  • Is a long. *
  • Its value is not reused for another module, even after a module is * unloaded. *
  • Does not change while a module remains loaded. *
  • Does not change when a module is reloaded. *
* *

* This method continues to return this module's unique identifier while * this module is in the UNLOADED state. * * @return The unique identifier of this module. */ long GetModuleId() const; /** * Returns this module's location. * *

* The location is the full path to the module's shared library. * This method continues to return this module's location * while this module is in the UNLOADED state. * * @return The string representation of this module's location. */ std::string GetLocation() const; /** * Returns the name of this module as specified by the * MITK_CREATE_MODULE CMake macro. The module * name together with a version must identify a unique module. * *

* This method continues to return this module's name while * this module is in the UNLOADED state. * * @return The name of this module. */ std::string GetName() const; /** * Returns the version of this module as specified by the * MITK_CREATE_MODULE CMake macro. If this module does not have a * specified version then {@link ModuleVersion#EmptyVersion} is returned. * *

* This method continues to return this module's version while * this module is in the UNLOADED state. * * @return The version of this module. */ ModuleVersion GetVersion() const; /** * Returns the value of the specified property for this module. The * method returns an empty string if the property is not found. * * @param key The name of the requested property. * @return The value of the requested property, or an empty string * if the property is undefined. */ std::string GetProperty(const std::string& key) const; private: friend class ModuleRegistry; friend class ServiceReferencePrivate; ModulePrivate* d; Module(); Module(const Module&); void Init(CoreModuleContext* coreCtx, ModuleInfo* info); void Uninit(); void Start(); void Stop(); }; } #ifdef MITK_HAS_UNORDERED_MAP_H namespace std { #elif defined(__GNUC__) namespace __gnu_cxx { #else namespace itk { #endif -template class hash; +template struct hash; template<> class hash { public: std::size_t operator()(const mitk::Module* module) const { #ifdef MITK_HAS_HASH_SIZE_T return hash()(reinterpret_cast(module)); #else std::size_t key = reinterpret_cast(module); return std::size_t(key & (~0U)); #endif } }; /** * \ingroup MicroServices */ namespace ModuleConstants { } } /** * \ingroup MicroServices */ MITK_CORE_EXPORT std::ostream& operator<<(std::ostream& os, const mitk::Module& module); /** * \ingroup MicroServices */ MITK_CORE_EXPORT std::ostream& operator<<(std::ostream& os, mitk::Module const * module); #endif // MITKMODULE_H diff --git a/Core/Code/Service/mitkModuleRegistry.h b/Core/Code/Service/mitkModuleRegistry.h index 0159036bb5..3c54a579b2 100644 --- a/Core/Code/Service/mitkModuleRegistry.h +++ b/Core/Code/Service/mitkModuleRegistry.h @@ -1,87 +1,87 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKMODULEREGISTRY_H #define MITKMODULEREGISTRY_H #include #include #include namespace mitk { class Module; -class ModuleInfo; +struct ModuleInfo; /** * \ingroup MicroServices * * Here we handle all the modules that are loaded in the framework. */ class MITK_CORE_EXPORT ModuleRegistry { public: /** * Get the module that has the specified module identifier. * * @param id The identifier of the module to get. * @return Module or null * if the module was not found. */ static Module* GetModule(long id); /** * Get the module that has specified module name. * * @param name The name of the module to get. * @return Module or null. */ static Module* GetModule(const std::string& name); /** * Get all known modules. * * @return A Module list with modules. */ static void GetModules(std::vector& modules); /** * Get all modules currently in module state LOADED. * * @return A List of Modules. */ static void GetLoadedModules(std::vector& modules); private: friend class ModuleInitializer; // disabled ModuleRegistry(); static void Register(ModuleInfo* info); static void UnRegister(const ModuleInfo* info); }; } #endif // MITKMODULEREGISTRY_H diff --git a/Core/Code/Service/mitkServiceException.h b/Core/Code/Service/mitkServiceException.h index 2afb2090d3..c471fa114f 100644 --- a/Core/Code/Service/mitkServiceException.h +++ b/Core/Code/Service/mitkServiceException.h @@ -1,114 +1,123 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKSERVICEEXCEPTION_H #define MITKSERVICEEXCEPTION_H #include #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4275) +#endif + /** * \ingroup MicroServices * * A service exception used to indicate that a service problem occurred. * *

* A ServiceException object is created by the framework or * to denote an exception condition in the service. An enum * type is used to identify the exception type for future extendability. * *

* This exception conforms to the general purpose exception chaining mechanism. */ class MITK_CORE_EXPORT ServiceException : public std::runtime_error { public: enum Type { /** * No exception type is unspecified. */ UNSPECIFIED = 0, /** * The service has been unregistered. */ UNREGISTERED = 1, /** * The service factory produced an invalid service object. */ FACTORY_ERROR = 2, /** * The service factory threw an exception. */ FACTORY_EXCEPTION = 3, /** * An error occurred invoking a remote service. */ REMOTE = 5, /** * The service factory resulted in a recursive call to itself for the * requesting module. */ FACTORY_RECURSION = 6 }; /** * Creates a ServiceException with the specified message, * type and exception cause. * * @param msg The associated message. * @param type The type for this exception. * @param cause The cause of this exception. */ ServiceException(const std::string& msg, const Type& type = UNSPECIFIED); ServiceException(const ServiceException& o); ServiceException& operator=(const ServiceException& o); ~ServiceException() throw() { } /** * Returns the type for this exception or UNSPECIFIED if the * type was unspecified or unknown. * * @return The type of this exception. */ Type GetType() const; private: /** * Type of service exception. */ Type type; }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } /** * \ingroup MicroServices * @{ */ MITK_CORE_EXPORT std::ostream& operator<<(std::ostream& os, const mitk::ServiceException& exc); /** @}*/ #endif // MITKSERVICEEXCEPTION_H diff --git a/Core/Code/Service/mitkServiceReference.h b/Core/Code/Service/mitkServiceReference.h index 1b57f1c0f5..ea19017807 100644 --- a/Core/Code/Service/mitkServiceReference.h +++ b/Core/Code/Service/mitkServiceReference.h @@ -1,240 +1,240 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKSERVICEREFERENCE_H #define MITKSERVICEREFERENCE_H #include #include #include #ifdef MITK_HAS_UNORDERED_MAP_H namespace std { #elif defined(__GNUC__) namespace __gnu_cxx { #else namespace itk { #endif -template class hash; +template struct hash; } namespace mitk { class Module; class ServiceRegistrationPrivate; class ServiceReferencePrivate; /** * \ingroup MicroServices * * A reference to a service. * *

* The framework returns ServiceReference objects from the * ModuleContext::GetServiceReference and * ModuleContext::GetServiceReferences methods. *

* A ServiceReference object may be shared between modules and * can be used to examine the properties of the service and to get the service * object. *

* Every service registered in the framework has a unique * ServiceRegistration object and may have multiple, distinct * ServiceReference objects referring to it. * ServiceReference objects associated with a * ServiceRegistration are considered equal * (more specifically, their operator==() * method will return true when compared). *

* If the same service object is registered multiple times, * ServiceReference objects associated with different * ServiceRegistration objects are not equal. * * @see ModuleContext::GetServiceReference * @see ModuleContext::GetServiceReferences * @see ModuleContext::GetService * @remarks This class is thread safe. */ class MITK_CORE_EXPORT ServiceReference { public: /** * Creates an invalid ServiceReference object. You can use * this object in boolean expressions and it will evaluate to * false. */ ServiceReference(); ServiceReference(const ServiceReference& ref); /** * Converts this ServiceReference instance into a boolean * expression. If this instance was default constructed or * the service it references has been unregistered, the conversion * returns false, otherwise it returns true. */ operator bool() const; /** * Releases any resources held or locked by this * ServiceReference and renders it invalid. */ ServiceReference& operator=(int null); ~ServiceReference(); /** * Returns the property value to which the specified property key is mapped * in the properties ServiceProperties object of the service * referenced by this ServiceReference object. * *

* Property keys are case-insensitive. * *

* This method continues to return property values after the service has * been unregistered. This is so references to unregistered services can * still be interrogated. * * @param key The property key. * @return The property value to which the key is mapped; an invalid Any * if there is no property named after the key. */ Any GetProperty(const std::string& key) const; /** * Returns a list of the keys in the ServiceProperties * object of the service referenced by this ServiceReference * object. * *

* This method will continue to return the keys after the service has been * unregistered. This is so references to unregistered services can * still be interrogated. * * @param keys A vector being filled with the property keys. */ void GetPropertyKeys(std::vector& keys) const; /** * Returns the module that registered the service referenced by this * ServiceReference object. * *

* This method must return 0 when the service has been * unregistered. This can be used to determine if the service has been * unregistered. * * @return The module that registered the service referenced by this * ServiceReference object; 0 if that * service has already been unregistered. * @see ModuleContext::RegisterService(const std::vector&, itk::LightObject*, const ServiceProperties&) */ Module* GetModule() const; /** * Returns the modules that are using the service referenced by this * ServiceReference object. Specifically, this method returns * the modules whose usage count for that service is greater than zero. * * @param modules A list of modules whose usage count for the service referenced * by this ServiceReference object is greater than * zero. */ void GetUsingModules(std::vector& modules) const; /** * Compares this ServiceReference with the specified * ServiceReference for order. * *

* If this ServiceReference and the specified * ServiceReference have the same {@link ServiceProperties::SERVICE_ID * service id} they are equal. This ServiceReference is less * than the specified ServiceReference if it has a lower * {@link ServiceProperties::SERVICE_RANKING service ranking} and greater if it has a * higher service ranking. Otherwise, if this ServiceReference * and the specified ServiceReference have the same * {@link ServiceProperties::SERVICE_RANKING service ranking}, this * ServiceReference is less than the specified * ServiceReference if it has a higher * {@link ServiceProperties::SERVICE_ID service id} and greater if it has a lower * service id. * * @param reference The ServiceReference to be compared. * @return Returns a false or true if this * ServiceReference is less than or greater * than the specified ServiceReference. */ bool operator<(const ServiceReference& reference) const; bool operator==(const ServiceReference& reference) const; ServiceReference& operator=(const ServiceReference& reference); protected: friend class ModulePrivate; friend class ModuleContext; friend class ServiceFilter; friend class ServiceRegistrationPrivate; friend class ServiceListeners; friend class LDAPFilter; template friend class ServiceTracker; template friend class ServiceTrackerPrivate; template friend class ModuleAbstractTracked; #ifdef MITK_HAS_UNORDERED_MAP_H friend class std::hash; #elif defined(__GNUC__) friend class __gnu_cxx::hash; #else friend struct itk::hash; #endif ServiceReference(ServiceRegistrationPrivate* reg); ServiceReferencePrivate* d; }; } MITK_CORE_EXPORT std::ostream& operator<<(std::ostream& os, const mitk::ServiceReference& serviceRef); #ifdef MITK_HAS_UNORDERED_MAP_H namespace std { #elif defined(__GNUC__) namespace __gnu_cxx { #else namespace itk { #endif template<> struct MITK_CORE_EXPORT hash { std::size_t operator()(const mitk::ServiceReference& sr) const; }; } #endif // MITKSERVICEREFERENCE_H diff --git a/CoreUI/Qmitk/QmitkPropertyDelegate.cpp b/CoreUI/Qmitk/QmitkPropertyDelegate.cpp index 684d1c10b2..8705665883 100644 --- a/CoreUI/Qmitk/QmitkPropertyDelegate.cpp +++ b/CoreUI/Qmitk/QmitkPropertyDelegate.cpp @@ -1,409 +1,411 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ +#ifndef NOMINMAX #define NOMINMAX +#endif #include "QmitkPropertyDelegate.h" #include "QmitkCustomVariants.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include #include #include #include #include #include QmitkPropertyDelegate::QmitkPropertyDelegate(QObject * /*parent*/) { } void QmitkPropertyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option , const QModelIndex &index) const { QVariant data = index.data(Qt::DisplayRole); QString name = data.value(); if(index.column() == 1 && data.type() == QVariant::Color) { QColor qcol = data.value(); painter->save(); painter->fillRect(option.rect, qcol); QRect rect = option.rect; rect.setWidth(rect.width()-1); rect.setHeight(rect.height()-1); QPen pen; pen.setWidth(1); painter->setPen(pen); painter->drawRect(rect); painter->restore(); } else { QStyledItemDelegate::paint(painter, option, index); } } QWidget* QmitkPropertyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option , const QModelIndex &index) const { QVariant data = index.data(Qt::EditRole); QVariant displayData = index.data(Qt::DisplayRole); QString name = index.model()->data(index.model()->index(index.row(), index.column()-1)).value(); if(data.isValid()) { QWidget* editorWidget = NULL; if(data.type() == QVariant::Color) { QPushButton* colorBtn = new QPushButton(parent); QColor color = data.value(); QColor result = QColorDialog::getColor(color); if(result.isValid()) { QPalette palette = colorBtn->palette(); palette.setColor(QPalette::Button, result); colorBtn->setPalette(palette); colorBtn->setStyleSheet(QString("background-color: %1;foreground-color: %1; border-style: none;").arg(result.name())); //colorBtn->setFlat(true); } // QColorDialog closed by 'Cancel' button, use the old property color else { QPalette palette = colorBtn->palette(); palette.setColor(QPalette::Button, color); colorBtn->setPalette(palette); colorBtn->setStyleSheet(QString("background-color: %1;foreground-color: %1; border-style: none;").arg(color.name())); } connect(colorBtn, SIGNAL(pressed()), this, SLOT(commitAndCloseEditor())); editorWidget = colorBtn; } /* else if(data.type() == QVariant::Bool) { QCheckBox *visibilityCheckBox = new QCheckBox(parent); connect(visibilityCheckBox, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return visibilityCheckBox; }*/ else if(data.type() == QVariant::Int) { QSpinBox* spinBox = new QSpinBox(parent); spinBox->setSingleStep(1); spinBox->setMinimum(std::numeric_limits::min()); spinBox->setMaximum(std::numeric_limits::max()); editorWidget = spinBox; } // see qt documentation. cast is correct, it would be obsolete if we // store doubles else if(static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); spinBox->setDecimals(2); spinBox->setSingleStep(0.1); if(name == "opacity") { spinBox->setMinimum(0.0); spinBox->setMaximum(1.0); } else { spinBox->setMinimum(std::numeric_limits::min()); spinBox->setMaximum(std::numeric_limits::max()); } editorWidget = spinBox; } else if(data.type() == QVariant::StringList) { QStringList entries = data.value(); QComboBox* comboBox = new QComboBox(parent); comboBox->setEditable(false); comboBox->addItems(entries); editorWidget = comboBox; } else { editorWidget = QStyledItemDelegate::createEditor(parent, option, index); } if ( editorWidget ) { // install event filter editorWidget->installEventFilter( const_cast(this) ); } return editorWidget; } else return new QLabel(displayData.toString(), parent); } void QmitkPropertyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QVariant data = index.data(Qt::EditRole); QVariant displayData = index.data(Qt::DisplayRole); if(data.isValid()) { if(data.type() == QVariant::Color) { /* QPushButton *colorBtn = qobject_cast(editor); QColor qcol = data.value(); colorBtn->setPalette(QPalette(qcol)); QColor result = QColorDialog::getColor(qcol); if(result.isValid()) { colorBtn->setPalette(QPalette(result)); } */ } /* else if(data.type() == QVariant::Bool) { QCheckBox *visibilityCheckBox = qobject_cast(editor); visibilityCheckBox->setChecked(data.toBool()); }*/ /*else*/ if(data.type() == QVariant::Int) { QSpinBox* spinBox = qobject_cast(editor); spinBox->setValue(data.toInt()); } // see qt documentation. cast is correct, it would be obsolete if we // store doubles else if(static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = qobject_cast(editor); spinBox->setValue(data.toDouble()); } else if(data.type() == QVariant::StringList) { QComboBox* comboBox = qobject_cast(editor); QString displayString = displayData.value(); comboBox->setCurrentIndex(comboBox->findData(displayString)); // connect(comboBox, SIGNAL(currentIndexChanged(int)), // this, SLOT(ComboBoxCurrentIndexChanged(int))); } else return QStyledItemDelegate::setEditorData(editor, index); } } void QmitkPropertyDelegate::setModelData(QWidget *editor, QAbstractItemModel* model , const QModelIndex &index) const { QVariant data = index.data(Qt::EditRole); QVariant displayData = index.data(Qt::DisplayRole); if(data.isValid()) { if(data.type() == QVariant::Color) { QWidget *colorBtn = qobject_cast(editor); QVariant colorVariant; colorVariant.setValue(colorBtn->palette().color(QPalette::Button)); model->setData(index, colorVariant); } else if(data.type() == QVariant::Int) { QSpinBox* spinBox = qobject_cast(editor); int intValue = spinBox->value(); QVariant intValueVariant; intValueVariant.setValue(static_cast(intValue)); model->setData(index, intValueVariant); } else if(static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = qobject_cast(editor); double doubleValue = spinBox->value(); QVariant doubleValueVariant; doubleValueVariant.setValue(static_cast(doubleValue)); model->setData(index, doubleValueVariant); } else if(data.type() == QVariant::StringList) { QString displayData = data.value(); QComboBox* comboBox = qobject_cast(editor); QString comboBoxValue = comboBox->currentText(); QVariant comboBoxValueVariant; comboBoxValueVariant.setValue(comboBoxValue); model->setData(index, comboBoxValueVariant); } else QStyledItemDelegate::setModelData(editor, model, index); } } void QmitkPropertyDelegate::commitAndCloseEditor() { QWidget* editor = 0; if(QPushButton *pushBtn = qobject_cast(sender())) { /* QColor result = QColorDialog::getColor(pushBtn->palette().color(QPalette::Window)); if(result.isValid()) { QPalette palette = pushBtn->palette(); palette.setColor(QPalette::Window, result); pushBtn->setPalette(palette); }*/ editor = pushBtn; } /* else if(QCheckBox *chkBox = qobject_cast(sender())) { editor = chkBox; }*/ if(editor) { emit commitData(editor); emit closeEditor(editor); } } void QmitkPropertyDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & /*index*/) const { /* QRect rect = option.rect; if (QCheckBox* checkBoxEditor = qobject_cast(editor)) { const QStyle *style = QApplication::style(); const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &option); const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &option); rect = QRect(option.rect.x()+ option.rect.width()/2-indicatorWidth/2, option.rect.y()+ option.rect.height()/2-indicatorHeight/2, indicatorWidth, indicatorHeight); } */ editor->setGeometry(option.rect); } void QmitkPropertyDelegate::ComboBoxCurrentIndexChanged( int /*index*/ ) { if(QComboBox *comboBox = qobject_cast(sender())) { emit commitData(comboBox); emit closeEditor(comboBox); } } void QmitkPropertyDelegate::SpinBoxValueChanged( const QString& /*value*/ ) { QAbstractSpinBox *spinBox = 0; if((spinBox = qobject_cast(sender())) || (spinBox = qobject_cast(sender()))) { emit commitData(spinBox); emit closeEditor(spinBox); } } void QmitkPropertyDelegate::showColorDialog() { } bool QmitkPropertyDelegate::eventFilter( QObject *o, QEvent *e ) { // filter all kind of events on our editor widgets // when certain events occur, repaint all render windows, because rendering relevant properties might have changed switch ( e->type() ) { case QEvent::KeyRelease: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::Wheel: case QEvent::FocusIn: { if( QWidget* editor = dynamic_cast(o) ) { emit commitData(editor); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); break; } default: { break; } } return false; } diff --git a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp index 0faefe7ea9..2a15796e1a 100644 --- a/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp +++ b/Modules/Bundles/org.mitk.gui.qt.segmentation/src/internal/QmitkSegmentationView.cpp @@ -1,1190 +1,1190 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision: 1.12 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkDataNodeObject.h" #include "mitkProperties.h" #include "mitkSegTool2D.h" #include "mitkGlobalInteraction.h" #include "QmitkStdMultiWidget.h" #include "QmitkNewSegmentationDialog.h" #include #include #include "QmitkSegmentationView.h" #include "QmitkSegmentationPostProcessing.h" #include "QmitkSegmentationOrganNamesHandling.cpp" #include #include //For Segmentation in rotated slices //TODO clean up includes #include "mitkVtkResliceInterpolationProperty.h" #include "mitkPlanarCircle.h" #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" const std::string QmitkSegmentationView::VIEW_ID = "org.mitk.views.segmentation"; // public methods QmitkSegmentationView::QmitkSegmentationView() :m_Parent(NULL) ,m_Controls(NULL) ,m_MultiWidget(NULL) ,m_RenderingManagerObserverTag(0) { } QmitkSegmentationView::~QmitkSegmentationView() { // delete m_PostProcessing; delete m_Controls; } void QmitkSegmentationView::NewNodesGenerated() { // ForceDisplayPreferencesUponAllImages(); } void QmitkSegmentationView::NewNodeObjectsGenerated(mitk::ToolManager::DataVectorType* nodes) { if (!nodes) return; mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); if (!toolManager) return; for (mitk::ToolManager::DataVectorType::iterator iter = nodes->begin(); iter != nodes->end(); ++iter) { this->FireNodeSelected( *iter ); // only last iteration meaningful, multiple generated objects are not taken into account here } } void QmitkSegmentationView::Activated() { // should be moved to ::BecomesVisible() or similar if( m_Controls ) { m_Controls->m_ManualToolSelectionBox->setEnabled( true ); m_Controls->m_OrganToolSelectionBox->setEnabled( true ); m_Controls->m_LesionToolSelectionBox->setEnabled( true ); m_Controls->m_SlicesInterpolator->Enable3DInterpolation( m_Controls->widgetStack->currentWidget() == m_Controls->pageManual ); //TODO Remove Observer itk::ReceptorMemberCommand::Pointer command1 = itk::ReceptorMemberCommand::New(); command1->SetCallbackFunction( this, &QmitkSegmentationView::RenderingManagerReinitialized ); m_RenderingManagerObserverTag = mitk::RenderingManager::GetInstance()->AddObserver( mitk::RenderingManagerViewsInitializedEvent(), command1 ); //Adding observers for node visibility to existing segmentations mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateAnd::Pointer isSegmentation = mitk::NodePredicateAnd::New( isImage, isBinary ); mitk::DataStorage::SetOfObjects::ConstPointer segmentations = this->GetDefaultDataStorage()->GetSubset( isSegmentation ); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = segmentations->begin(); iter != segmentations->end(); ++iter) { mitk::DataNode* node = *iter; itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); m_WorkingDataObserverTags.insert( std::pair( node, node->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); } if(segmentations->Size() > 0) { FireNodeSelected(segmentations->ElementAt(0)); segmentations->ElementAt(0)->GetProperty("visible")->Modified(); } } } void QmitkSegmentationView::Deactivated() { if( m_Controls ) { mitk::RenderingManager::GetInstance()->RemoveObserver( m_RenderingManagerObserverTag ); m_Controls->m_ManualToolSelectionBox->setEnabled( false ); //deactivate all tools m_Controls->m_ManualToolSelectionBox->GetToolManager()->ActivateTool(-1); m_Controls->m_OrganToolSelectionBox->setEnabled( false ); m_Controls->m_LesionToolSelectionBox->setEnabled( false ); m_Controls->m_SlicesInterpolator->EnableInterpolation( false ); //Removing all observers for ( NodeTagMapType::iterator dataIter = m_WorkingDataObserverTags.begin(); dataIter != m_WorkingDataObserverTags.end(); ++dataIter ) { (*dataIter).first->GetProperty("visible")->RemoveObserver( (*dataIter).second ); } m_WorkingDataObserverTags.clear(); // gets the context of the "Mitk" (Core) module (always has id 1) // TODO Workaround until CTL plugincontext is available mitk::ModuleContext* context = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); // Workaround end mitk::ServiceReference serviceRef = context->GetServiceReference(); //mitk::ServiceReference serviceRef = mitk::GetModuleContext()->GetServiceReference(); mitk::PlanePositionManagerService* service = dynamic_cast(context->GetService(serviceRef)); service->RemoveAllPlanePositions(); } } void QmitkSegmentationView::StdMultiWidgetAvailable( QmitkStdMultiWidget& stdMultiWidget ) { SetMultiWidget(&stdMultiWidget); } void QmitkSegmentationView::StdMultiWidgetNotAvailable() { SetMultiWidget(NULL); } void QmitkSegmentationView::StdMultiWidgetClosed( QmitkStdMultiWidget& /*stdMultiWidget*/ ) { SetMultiWidget(NULL); } void QmitkSegmentationView::SetMultiWidget(QmitkStdMultiWidget* multiWidget) { if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { coordinator->RemoveObserver( m_SlicesRotationObserverTag1 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { coordinator->RemoveObserver( m_SlicesRotationObserverTag2 ); } } // save the current multiwidget as the working widget m_MultiWidget = multiWidget; //TODO Remove Observers if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkSegmentationView::SliceRotation ); m_SlicesRotationObserverTag1 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkSegmentationView::SliceRotation ); m_SlicesRotationObserverTag2 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } } //TODO End Remove Observers if (m_Parent) { m_Parent->setEnabled(m_MultiWidget); } // tell the interpolation about toolmanager and multiwidget (and data storage) if (m_Controls && m_MultiWidget) { mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); m_Controls->m_SlicesInterpolator->SetDataStorage( *(this->GetDefaultDataStorage())); m_Controls->m_SlicesInterpolator->Initialize( toolManager, m_MultiWidget ); } } void QmitkSegmentationView::OnPreferencesChanged(const berry::IBerryPreferences*) { ForceDisplayPreferencesUponAllImages(); } //TODO remove function void QmitkSegmentationView::RenderingManagerReinitialized(const itk::EventObject&) { CheckImageAlignment(); } //TODO remove function void QmitkSegmentationView::SliceRotation(const itk::EventObject&) { CheckImageAlignment(); } // protected slots void QmitkSegmentationView::CreateNewSegmentation() { mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull()) { if (image->GetDimension()>2) { // ask about the name and organ type of the new segmentation QmitkNewSegmentationDialog* dialog = new QmitkNewSegmentationDialog( m_Parent ); // needs a QWidget as parent, "this" is not QWidget QString storedList = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); QStringList organColors; if (storedList.isEmpty()) { organColors = GetDefaultOrganColorString(); } else { /* a couple of examples of how organ names are stored: a simple item is built up like 'name#AABBCC' where #AABBCC is the hexadecimal notation of a color as known from HTML items are stored separated by ';' this makes it necessary to escape occurrences of ';' in name. otherwise the string "hugo;ypsilon#AABBCC;eugen#AABBCC" could not be parsed as two organs but we would get "hugo" and "ypsilon#AABBCC" and "eugen#AABBCC" so the organ name "hugo;ypsilon" is stored as "hugo\;ypsilon" and must be unescaped after loading the following lines could be one split with Perl's negative lookbehind */ // recover string list from BlueBerry view's preferences QString storedString = QString::fromStdString( this->GetPreferences()->GetByteArray("Organ-Color-List","") ); MITK_DEBUG << "storedString: " << storedString.toStdString(); // match a string consisting of any number of repetitions of either "anything but ;" or "\;". This matches everything until the next unescaped ';' QRegExp onePart("(?:[^;]|\\\\;)*"); MITK_DEBUG << "matching " << onePart.pattern().toStdString(); int count = 0; int pos = 0; while( (pos = onePart.indexIn( storedString, pos )) != -1 ) { ++count; int length = onePart.matchedLength(); if (length == 0) break; QString matchedString = storedString.mid(pos, length); MITK_DEBUG << " Captured length " << length << ": " << matchedString.toStdString(); pos += length + 1; // skip separating ';' // unescape possible occurrences of '\;' in the string matchedString.replace("\\;", ";"); // add matched string part to output list organColors << matchedString; } MITK_DEBUG << "Captured " << count << " organ name/colors"; } dialog->SetSuggestionList( organColors ); int dialogReturnValue = dialog->exec(); if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar // ask the user about an organ type and name, add this information to the image's (!) propertylist // create a new image of the same dimensions and smallest possible pixel type mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); mitk::Tool* firstTool = toolManager->GetToolById(0); if (firstTool) { try { mitk::DataNode::Pointer emptySegmentation = firstTool->CreateEmptySegmentationNode( image, dialog->GetSegmentationName().toStdString(), dialog->GetColor() ); //Here we change the reslice interpolation mode for a segmentation, so that contours in rotated slice can be shown correctly emptySegmentation->SetProperty( "reslice interpolation", mitk::VtkResliceInterpolationProperty::New(VTK_RESLICE_LINEAR) ); // initialize showVolume to false to prevent recalculating the volume while working on the segmentation emptySegmentation->SetProperty( "showVolume", mitk::BoolProperty::New( false ) ); if (!emptySegmentation) return; // could be aborted by user UpdateOrganList( organColors, dialog->GetSegmentationName(), dialog->GetColor() ); /* escape ';' here (replace by '\;'), see longer comment above */ std::string stringForStorage = organColors.replaceInStrings(";","\\;").join(";").toStdString(); MITK_DEBUG << "Will store: " << stringForStorage; this->GetPreferences()->PutByteArray("Organ-Color-List", stringForStorage ); this->GetPreferences()->Flush(); if(m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0)) { m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0)->SetSelected(false); } //emptySegmentation->SetSelected(true); this->GetDefaultDataStorage()->Add( emptySegmentation, node ); // add as a child, because the segmentation "derives" from the original this->FireNodeSelected( emptySegmentation ); this->OnSelectionChanged( emptySegmentation ); this->SetToolManagerSelection(node, emptySegmentation); } catch (std::bad_alloc) { QMessageBox::warning(NULL,"Create new segmentation","Could not allocate memory for new segmentation"); } } } else { QMessageBox::information(NULL,"Segmentation","Segmentation is currently not supported for 2D images"); } } } else { MITK_ERROR << "'Create new segmentation' button should never be clickable unless a patient image is selected..."; } } void QmitkSegmentationView::OnWorkingNodeVisibilityChanged(/*const itk::Object* caller, const itk::EventObject& e*/) { if (!m_Parent || !m_Parent->isVisible()) return; // The new selection behaviour is: // // When clicking on the checkbox of a segmentation the node will e selected and its reference node either // The previous selected segmentation (if there is one) will be deselected. Additionally a reinit on the // selected segmenation will be performed. // If more than one segmentation is selected the tools will be disabled. if (!m_Controls) return; // might happen on initialization (preferences loaded) mitk::DataNode::Pointer referenceDataNew; mitk::DataNode::Pointer workingData; bool workingNodeIsVisible (true); mitk::DataNode::Pointer refTemp; unsigned int numberOfSelectedSegmentations (0); // iterate all images mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDefaultDataStorage()->GetSubset( isImage ); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { mitk::DataNode* node = *iter; // apply display preferences ApplyDisplayOptions(node); bool isSegmentation(false); node->GetBoolProperty("binary", isSegmentation); if (node->IsSelected() && isSegmentation) { workingNodeIsVisible = node->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))); if (!workingNodeIsVisible) return; numberOfSelectedSegmentations++; workingData = node; if (this->GetDefaultDataStorage()->GetSources(node)->Size() != 0) { referenceDataNew = this->GetDefaultDataStorage()->GetSources(node)->ElementAt(0); } if (workingNodeIsVisible && referenceDataNew) referenceDataNew->SetVisibility(true); //set comboBox to reference image disconnect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->refImageSelector->setCurrentIndex( m_Controls->refImageSelector->Find(referenceDataNew) ); connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); continue; } if (workingData.IsNull() || (workingNodeIsVisible && node != referenceDataNew)) { node->SetVisibility((false)); } } if(numberOfSelectedSegmentations == 1) SetToolManagerSelection(referenceDataNew, workingData); mitk::DataStorage::SetOfObjects::Pointer temp = mitk::DataStorage::SetOfObjects::New(); temp->InsertElement(0,workingData); mitk::TimeSlicedGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(temp); // initialize the views to the bounding geometry mitk::RenderingManager::GetInstance()->InitializeViews(bounds); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSegmentationView::NodeRemoved(const mitk::DataNode* node) { bool isSeg(false); bool isHelperObject(false); node->GetBoolProperty("helper object", isHelperObject); if(node->GetBoolProperty("binary", isSeg) && !isHelperObject) { mitk::DataNode* tempNode = const_cast(node); node->GetProperty("visible")->RemoveObserver( m_WorkingDataObserverTags[tempNode] ); m_WorkingDataObserverTags.erase(tempNode); this->SetToolManagerSelection(NULL, NULL); } } void QmitkSegmentationView::CreateSegmentationFromSurface() { mitk::DataNode::Pointer surfaceNode = m_Controls->MaskSurfaces->GetSelectedNode(); mitk::Surface::Pointer surface(0); if(surfaceNode.IsNotNull()) surface = dynamic_cast ( surfaceNode->GetData() ); if(surface.IsNull()) { this->HandleException( "No surface selected.", m_Parent, true); return; } mitk::DataNode::Pointer imageNode = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); mitk::Image::Pointer image(0); if (imageNode.IsNotNull()) image = dynamic_cast( imageNode->GetData() ); if(image.IsNull()) { this->HandleException( "No image selected.", m_Parent, true); return; } mitk::SurfaceToImageFilter::Pointer s2iFilter = mitk::SurfaceToImageFilter::New(); s2iFilter->MakeOutputBinaryOn(); s2iFilter->SetInput(surface); s2iFilter->SetImage(image); s2iFilter->Update(); mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); std::string nameOfResultImage = imageNode->GetName(); nameOfResultImage.append(surfaceNode->GetName()); resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) ); resultNode->SetProperty("binary", mitk::BoolProperty::New(true) ); resultNode->SetData( s2iFilter->GetOutput() ); this->GetDataStorage()->Add(resultNode, imageNode); } void QmitkSegmentationView::ManualToolSelected(int id) { // disable crosshair movement when a manual drawing tool is active (otherwise too much visual noise) if (m_MultiWidget) { if (id >= 0) { m_MultiWidget->DisableNavigationControllerEventListening(); m_MultiWidget->SetWidgetPlaneMode(0); } else { m_MultiWidget->EnableNavigationControllerEventListening(); } } } void QmitkSegmentationView::ToolboxStackPageChanged(int id) { // interpolation only with manual tools visible m_Controls->m_SlicesInterpolator->EnableInterpolation( id == 0 ); if( id == 0 ) { mitk::DataNode::Pointer workingData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0); if( workingData.IsNotNull() ) { m_Controls->lblSegmentation->setText( workingData->GetName().c_str() ); m_Controls->lblSegImage->show(); m_Controls->lblSegmentation->show(); } } else { m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } // this is just a workaround, should be removed when all tools support 3D+t if (id==2) // lesions { mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull()) { if (image->GetDimension()>3) { m_Controls->widgetStack->setCurrentIndex(0); QMessageBox::information(NULL,"Segmentation","Lesion segmentation is currently not supported for 4D images"); } } } } } // protected void QmitkSegmentationView::OnComboBoxSelectionChanged( const mitk::DataNode* node ) { mitk::DataNode* selectedNode = const_cast(node); if( selectedNode != NULL ) { m_Controls->refImageSelector->show(); m_Controls->lblReferenceImageSelectionWarning->hide(); bool isBinary(false); selectedNode->GetBoolProperty("binary", isBinary); if ( isBinary ) { FireNodeSelected(selectedNode); selectedNode->SetVisibility(true); } else if (node != m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0)) { if (m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0)) m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0)->SetVisibility(false); if (m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0)) { m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0)->SetVisibility(false); } FireNodeSelected(selectedNode); selectedNode->SetVisibility(true); SetToolManagerSelection(selectedNode, NULL); } } else { m_Controls->refImageSelector->hide(); m_Controls->lblReferenceImageSelectionWarning->show(); } } void QmitkSegmentationView::OnShowMarkerNodes (bool state) { mitk::SegTool2D::Pointer manualSegmentationTool; unsigned int numberOfExistingTools = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetTools().size(); for(unsigned int i = 0; i < numberOfExistingTools; i++) -{ + { manualSegmentationTool = dynamic_cast(m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetToolById(i)); if (manualSegmentationTool) { - if(state == Qt::Checked) + if(state == true) { manualSegmentationTool->SetShowMarkerNodes( true ); -} + } else { manualSegmentationTool->SetShowMarkerNodes( false ); } } } } void QmitkSegmentationView::On3DInterpolationEnabled (bool state) { mitk::SegTool2D::Pointer manualSegmentationTool; unsigned int numberOfExistingTools = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetTools().size(); for(unsigned int i = 0; i < numberOfExistingTools; i++) { manualSegmentationTool = dynamic_cast(m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetToolById(i)); if (manualSegmentationTool) { manualSegmentationTool->Enable3DInterpolation( state ); } } } void QmitkSegmentationView::OnSelectionChanged(mitk::DataNode* node) { std::vector nodes; nodes.push_back( node ); this->OnSelectionChanged( nodes ); } void QmitkSegmentationView::OnSurfaceSelectionChanged() { // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull())) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); } void QmitkSegmentationView::OnSelectionChanged(std::vector nodes) { // if the selected node is a contourmarker if ( !nodes.empty() ) { std::string markerName = "Position"; unsigned int numberOfNodes = nodes.size(); std::string nodeName = nodes.at( 0 )->GetName(); if ( ( numberOfNodes == 1 ) && ( nodeName.find( markerName ) == 0) ) { this->OnContourMarkerSelected( nodes.at( 0 ) ); } } // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull())) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); if (!m_Parent || !m_Parent->isVisible()) return; // reaction to BlueBerry selection events // this method will try to figure out if a relevant segmentation and its corresponding original image were selected // a warning is issued if the selection is invalid // appropriate reactions are triggered otherwise mitk::DataNode::Pointer referenceData = FindFirstRegularImage( nodes ); //m_Controls->refImageSelector->GetSelectedNode(); //FindFirstRegularImage( nodes ); mitk::DataNode::Pointer workingData = FindFirstSegmentation( nodes ); if(referenceData.IsNull() && workingData.IsNull()) return; bool invalidSelection( !nodes.empty() && ( nodes.size() > 2 || // maximum 2 selected nodes (nodes.size() == 2 && (workingData.IsNull() || referenceData.IsNull()) ) || // with two nodes, one must be the original image, one the segmentation ( workingData.GetPointer() == referenceData.GetPointer() ) //one node is selected as reference and working image // one item is always ok (might be working or reference or nothing ) ); if (invalidSelection) { // TODO visible warning when two images are selected MITK_ERROR << "WARNING: No image, too many (>2) or two equal images were selected."; workingData = NULL; if( m_Controls->refImageSelector->GetSelectedNode().IsNull() ) referenceData = NULL; } if ( workingData.IsNotNull() && referenceData.IsNull() ) { // find the DataStorage parent of workingData // try to find a "normal image" parent, select this as reference image mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary ); mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary ); mitk::DataStorage::SetOfObjects::ConstPointer possibleParents = this->GetDefaultDataStorage()->GetSources( workingData, isNormalImage ); if (possibleParents->size() > 0) { if (possibleParents->size() > 1) { // TODO visible warning for this rare case MITK_ERROR << "Selected binary image has multiple parents. Using arbitrary first one for segmentation."; } referenceData = (*possibleParents)[0]; } NodeTagMapType::iterator searchIter = m_WorkingDataObserverTags.find( workingData ); if ( searchIter == m_WorkingDataObserverTags.end() ) { //MITK_INFO<<"Creating new observer"; itk::SimpleMemberCommand::Pointer command = itk::SimpleMemberCommand::New(); command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); m_WorkingDataObserverTags.insert( std::pair( workingData, workingData->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); workingData->GetProperty("visible")->Modified(); // itk::MemberCommand::Pointer command = itk::MemberCommand::New(); // command->SetCallbackFunction(this, &QmitkSegmentationView::OnWorkingNodeVisibilityChanged); // m_WorkingDataObserverTags.insert( std::pair( workingData, workingData->GetProperty("visible")->AddObserver( itk::ModifiedEvent(), command ) ) ); // workingData->GetProperty("visible")->Modified(); return; } if(workingData->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")))) { //set comboBox to reference image disconnect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->refImageSelector->setCurrentIndex( m_Controls->refImageSelector->Find(workingData) ); connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull()) || (!referenceData)) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); SetToolManagerSelection(referenceData, workingData); FireNodeSelected(workingData); } else { SetToolManagerSelection(NULL, NULL); FireNodeSelected(workingData); } } else { //set comboBox to reference image disconnect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); m_Controls->refImageSelector->setCurrentIndex( m_Controls->refImageSelector->Find(referenceData) ); connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); // if Image and Surface are selected, enable button if ( (m_Controls->refImageSelector->GetSelectedNode().IsNull()) || (m_Controls->MaskSurfaces->GetSelectedNode().IsNull()) || (!referenceData)) m_Controls->CreateSegmentationFromSurface->setEnabled(false); else m_Controls->CreateSegmentationFromSurface->setEnabled(true); SetToolManagerSelection(referenceData, workingData); FireNodeSelected(referenceData); } } void QmitkSegmentationView::OnContourMarkerSelected(const mitk::DataNode *node) { //TODO renderWindow anders bestimmen, siehe CheckAlignment QmitkRenderWindow* selectedRenderWindow = 0; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); bool PlanarFigureInitializedWindow = false; // find initialized renderwindow if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } if (!selectedRenderWindow && node->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } // make node visible if (selectedRenderWindow) { std::string nodeName = node->GetName(); unsigned int t = nodeName.find_last_of(" "); unsigned int id = atof(nodeName.substr(t+1).c_str())-1; // gets the context of the "Mitk" (Core) module (always has id 1) // TODO Workaround until CTL plugincontext is available mitk::ModuleContext* context = mitk::ModuleRegistry::GetModule(1)->GetModuleContext(); // Workaround end mitk::ServiceReference serviceRef = context->GetServiceReference(); //mitk::ServiceReference serviceRef = mitk::GetModuleContext()->GetServiceReference(); mitk::PlanePositionManagerService* service = dynamic_cast(context->GetService(serviceRef)); selectedRenderWindow->GetSliceNavigationController()->ExecuteOperation(service->GetPlanePosition(id)); selectedRenderWindow->GetRenderer()->GetDisplayGeometry()->Fit(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } mitk::DataNode::Pointer QmitkSegmentationView::FindFirstRegularImage( std::vector nodes ) { if (nodes.empty()) return NULL; for(unsigned int i = 0; i < nodes.size(); ++i) { //mitk::DataNode::Pointer node = i.value() bool isImage(false); if (nodes.at(i)->GetData()) { isImage = dynamic_cast(nodes.at(i)->GetData()) != NULL; } // make sure this is not a binary image bool isSegmentation(false); nodes.at(i)->GetBoolProperty("binary", isSegmentation); // return first proper mitk::Image if (isImage && !isSegmentation) return nodes.at(i); } return NULL; } mitk::DataNode::Pointer QmitkSegmentationView::FindFirstSegmentation( std::vector nodes ) { if (nodes.empty()) return NULL; for(unsigned int i = 0; i < nodes.size(); ++i) { bool isImage(false); if (nodes.at(i)->GetData()) { isImage = dynamic_cast(nodes.at(i)->GetData()) != NULL; } bool isSegmentation(false); nodes.at(i)->GetBoolProperty("binary", isSegmentation); // return first proper binary mitk::Image if (isImage && isSegmentation) { return nodes.at(i); } } return NULL; } void QmitkSegmentationView::SetToolManagerSelection(const mitk::DataNode* referenceData, const mitk::DataNode* workingData) { // called as a result of new BlueBerry selections // tells the ToolManager for manual segmentation about new selections // updates GUI information about what the user should select mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); toolManager->SetReferenceData(const_cast(referenceData)); toolManager->SetWorkingData( const_cast(workingData)); // check original image m_Controls->btnNewSegmentation->setEnabled(referenceData != NULL); if (referenceData) { m_Controls->lblReferenceImageSelectionWarning->hide(); } else { m_Controls->lblReferenceImageSelectionWarning->show(); m_Controls->lblWorkingImageSelectionWarning->hide(); m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } //TODO remove statement // check, wheter reference image is aligned like render windows. Otherwise display a visible warning (because 2D tools will probably not work) CheckImageAlignment(); // check segmentation if (referenceData) { if (!workingData) { m_Controls->lblWorkingImageSelectionWarning->show(); if( m_Controls->widgetStack->currentIndex() == 0 ) { m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); } } else { m_Controls->lblWorkingImageSelectionWarning->hide(); this->FireNodeSelected(const_cast(workingData)); if( m_Controls->widgetStack->currentIndex() == 0 ) { m_Controls->lblSegmentation->setText( workingData->GetName().c_str() ); m_Controls->lblSegmentation->show(); m_Controls->lblSegImage->show(); } } } } //TODO remove function void QmitkSegmentationView::CheckImageAlignment() { bool wrongAlignment(true); mitk::DataNode::Pointer node = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); if (node.IsNotNull()) { mitk::Image::Pointer image = dynamic_cast( node->GetData() ); if (image.IsNotNull() && m_MultiWidget) { wrongAlignment = !( IsRenderWindowAligned(m_MultiWidget->GetRenderWindow1(), image ) && IsRenderWindowAligned(m_MultiWidget->GetRenderWindow2(), image ) && IsRenderWindowAligned(m_MultiWidget->GetRenderWindow3(), image ) ); } if (wrongAlignment) { m_Controls->lblAlignmentWarning->show(); } } } //TODO remove function bool QmitkSegmentationView::IsRenderWindowAligned(QmitkRenderWindow* renderWindow, mitk::Image* image) { if (!renderWindow) return false; // for all 2D renderwindows of m_MultiWidget check alignment mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( renderWindow->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; int affectedDimension(-1); int affectedSlice(-1); return mitk::SegTool2D::DetermineAffectedImageSlice( image, displayPlane, affectedDimension, affectedSlice ); } //TODO remove function void QmitkSegmentationView::ForceDisplayPreferencesUponAllImages() { if (!m_Parent || !m_Parent->isVisible()) return; // check all images and segmentations in DataStorage: // (items in brackets are implicitly done by previous steps) // 1. // if a reference image is selected, // show the reference image // and hide all other images (orignal and segmentation), // (and hide all segmentations of the other original images) // and show all the reference's segmentations // if no reference image is selected, do do nothing // // 2. // if a segmentation is selected, // show it // (and hide all all its siblings (childs of the same parent, incl, NULL parent)) // if no segmentation is selected, do nothing if (!m_Controls) return; // might happen on initialization (preferences loaded) mitk::DataNode::Pointer referenceData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetReferenceData(0); mitk::DataNode::Pointer workingData = m_Controls->m_ManualToolSelectionBox->GetToolManager()->GetWorkingData(0); // 1. if (referenceData.IsNotNull()) { // iterate all images mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer allImages = this->GetDefaultDataStorage()->GetSubset( isImage ); //mitk::DataStorage::SetOfObjects::ConstPointer allSegmentationChilds = this->GetDefaultDataStorage()->GetDerivations(referenceData, isImage ); for ( mitk::DataStorage::SetOfObjects::const_iterator iter = allImages->begin(); iter != allImages->end(); ++iter) { mitk::DataNode* node = *iter; // apply display preferences ApplyDisplayOptions(node); // set visibility if(!node->IsSelected() || (node->IsSelected() && !node->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1"))))) node->SetVisibility((node == referenceData) || node->IsSelected() ); } } // 2. //if (workingData.IsNotNull() && !workingData->IsSelected()) //{ // workingData->SetVisibility(true); //} mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkSegmentationView::ApplyDisplayOptions(mitk::DataNode* node) { if (!node) return; bool isBinary(false); node->GetPropertyValue("binary", isBinary); if (isBinary) { node->SetProperty( "outline binary", mitk::BoolProperty::New( this->GetPreferences()->GetBool("draw outline", true)) ); node->SetProperty( "outline width", mitk::FloatProperty::New( 2.0 ) ); node->SetProperty( "opacity", mitk::FloatProperty::New( this->GetPreferences()->GetBool("draw outline", true) ? 1.0 : 0.3 ) ); node->SetProperty( "volumerendering", mitk::BoolProperty::New( this->GetPreferences()->GetBool("volume rendering", false) ) ); } } void QmitkSegmentationView::CreateQtPartControl(QWidget* parent) { // setup the basic GUI of this view m_Parent = parent; m_Controls = new Ui::QmitkSegmentationControls; m_Controls->setupUi(parent); m_Controls->lblWorkingImageSelectionWarning->hide(); m_Controls->lblAlignmentWarning->hide(); m_Controls->lblSegImage->hide(); m_Controls->lblSegmentation->hide(); m_Controls->refImageSelector->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->refImageSelector->SetPredicate(mitk::NodePredicateDataType::New("Image")); if( m_Controls->refImageSelector->GetSelectedNode().IsNotNull() ) m_Controls->lblReferenceImageSelectionWarning->hide(); else m_Controls->refImageSelector->hide(); mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); toolManager->SetDataStorage( *(this->GetDefaultDataStorage()) ); assert ( toolManager ); // all part of open source MITK m_Controls->m_ManualToolSelectionBox->SetGenerateAccelerators(true); m_Controls->m_ManualToolSelectionBox->SetToolGUIArea( m_Controls->m_ManualToolGUIContainer ); m_Controls->m_ManualToolSelectionBox->SetDisplayedToolGroups("Add Subtract Paint Wipe 'Region Growing' Correction Fill Erase"); m_Controls->m_ManualToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceAndWorkingData ); // available only in the 3M application if ( !m_Controls->m_OrganToolSelectionBox->children().count() ) { m_Controls->widgetStack->setItemEnabled( 1, false ); } m_Controls->m_OrganToolSelectionBox->SetToolManager( *toolManager ); m_Controls->m_OrganToolSelectionBox->SetToolGUIArea( m_Controls->m_OrganToolGUIContainer ); m_Controls->m_OrganToolSelectionBox->SetDisplayedToolGroups("'Hippocampus left' 'Hippocampus right' 'Lung left' 'Lung right' 'Liver' 'Heart LV' 'Endocard LV' 'Epicard LV' 'Prostate'"); m_Controls->m_OrganToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceData ); // available only in the 3M application if ( !m_Controls->m_LesionToolSelectionBox->children().count() ) { m_Controls->widgetStack->setItemEnabled( 2, false ); } m_Controls->m_LesionToolSelectionBox->SetToolManager( *toolManager ); m_Controls->m_LesionToolSelectionBox->SetToolGUIArea( m_Controls->m_LesionToolGUIContainer ); m_Controls->m_LesionToolSelectionBox->SetDisplayedToolGroups("'Lymph Node'"); m_Controls->m_LesionToolSelectionBox->SetEnabledMode( QmitkToolSelectionBox::EnabledWithReferenceData ); toolManager->NewNodesGenerated += mitk::MessageDelegate( this, &QmitkSegmentationView::NewNodesGenerated ); // update the list of segmentations toolManager->NewNodeObjectsGenerated += mitk::MessageDelegate1( this, &QmitkSegmentationView::NewNodeObjectsGenerated ); // update the list of segmentations // create signal/slot connections connect( m_Controls->refImageSelector, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnComboBoxSelectionChanged( const mitk::DataNode* ) ) ); connect( m_Controls->btnNewSegmentation, SIGNAL(clicked()), this, SLOT(CreateNewSegmentation()) ); connect( m_Controls->CreateSegmentationFromSurface, SIGNAL(clicked()), this, SLOT(CreateSegmentationFromSurface()) ); connect( m_Controls->m_ManualToolSelectionBox, SIGNAL(ToolSelected(int)), this, SLOT(ManualToolSelected(int)) ); connect( m_Controls->widgetStack, SIGNAL(currentChanged(int)), this, SLOT(ToolboxStackPageChanged(int)) ); connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSurfaceSelectionChanged( ) ) ); connect(m_Controls->MaskSurfaces, SIGNAL( OnSelectionChanged( const mitk::DataNode* ) ), this, SLOT( OnSurfaceSelectionChanged( ) ) ); connect(m_Controls->m_SlicesInterpolator, SIGNAL(SignalShowMarkerNodes(bool)), this, SLOT(OnShowMarkerNodes(bool))); connect(m_Controls->m_SlicesInterpolator, SIGNAL(Signal3DInterpolationEnabled(bool)), this, SLOT(On3DInterpolationEnabled(bool))); m_Controls->MaskSurfaces->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->MaskSurfaces->SetPredicate(mitk::NodePredicateDataType::New("Surface")); //// create helper class to provide context menus for segmentations in data manager // m_PostProcessing = new QmitkSegmentationPostProcessing(this->GetDefaultDataStorage(), this, m_Parent); } //void QmitkSegmentationView::OnPlaneModeChanged(int i) //{ // //if plane mode changes, disable all tools // if (m_MultiWidget) // { // mitk::ToolManager* toolManager = m_Controls->m_ManualToolSelectionBox->GetToolManager(); // // if (toolManager) // { // if (toolManager->GetActiveToolID() >= 0) // { // toolManager->ActivateTool(-1); // } // else // { // m_MultiWidget->EnableNavigationControllerEventListening(); // } // } // } //} // ATTENTION some methods for handling the known list of (organ names, colors) are defined in QmitkSegmentationOrganNamesHandling.cpp diff --git a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp index dbbba8c28f..875015a42f 100644 --- a/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp +++ b/Modules/DiffusionImaging/IODataStructures/FiberBundle/mitkFiberBundle.cpp @@ -1,1863 +1,1821 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-03-31 16:40:27 +0200 (Mi, 31 Mrz 2010) $ Version: $Revision: 21975 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkFiberBundle.h" #include #include #include #include #include #include #include #include #include //#include /* statics values to define the position of a fiberTractPoint * related to the plane of a ROI */ const int mitk::FiberBundle::TRACTPOINT_BACKFACE = 0; const int mitk::FiberBundle::TRACTPOINT_ON_PLANE = 1; const int mitk::FiberBundle::TRACTPOINT_FRNTFACE = 2; // implementation of all essential methods from superclass mitk::FiberBundle::FiberBundle() { m_GroupFiberBundle = FiberGroupType::New(); m_TractContainer = ContainerType::New(); //by default set a standard geometry, usually geometry is set by the user on initializing //a mitkFiberBundle Object mitk::Geometry3D::Pointer fbgeometry = mitk::Geometry3D::New(); fbgeometry->SetIdentity(); this->SetGeometry(fbgeometry); /* for debugging only */ m_debugITKContainer = itkStochTractContainerType::New(); } mitk::FiberBundle::~FiberBundle() { } void mitk::FiberBundle::SetBounds(float* b) { m_boundsFB[0] = b[0]; m_boundsFB[1] = b[1]; m_boundsFB[2] = b[2]; } void mitk::FiberBundle::SetBounds(double* b) { m_boundsFB[0] = b[0]; m_boundsFB[1] = b[1]; m_boundsFB[2] = b[2]; } float* mitk::FiberBundle::GetBounds() { return m_boundsFB; } void mitk::FiberBundle::PushPoint(int fiberIndex, ContainerPointType point) { if( (unsigned)fiberIndex >= m_TractContainer->Size() ) { fiberIndex = m_TractContainer->Size(); ContainerTractType::Pointer tract = ContainerTractType::New(); tract->InsertElement(tract->Size(),point); m_TractContainer->InsertElement(fiberIndex, tract); } else if(fiberIndex>=0) { m_TractContainer->ElementAt(fiberIndex)->InsertElement(m_TractContainer->ElementAt(fiberIndex)->Size(), point); } } void mitk::FiberBundle::PushTract(ContainerTractType::Pointer tract) { m_TractContainer->InsertElement(m_TractContainer->Size(), tract); } mitk::FiberBundle::Pointer mitk::FiberBundle::JoinBundle(mitk::FiberBundle::Pointer bundle) { mitk::FiberBundle::Pointer retval = mitk::FiberBundle::New(); retval->SetGeometry(this->GetGeometry()); retval->SetBounds(this->m_boundsFB); retval->InsertBundle(this); retval->InsertBundle(bundle); return retval; } void mitk::FiberBundle::InsertBundle(mitk::FiberBundle::Pointer bundle) { // INCOMPLETE, SHOULD CHECK FOR DIFFERENT GEOMETRIES IN THIS+BUNDLE // DO INDEX1 -> WORLD -> INDEX2 TRANSFORMATION, IF THEY ARE DIFFERENT. int num = this->GetNumTracts(); FiberGroupType::Pointer groupFiberBundle = bundle->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } dtiTract->SetId(num++); this->addSingleDTITract(dtiTract); } ContainerType::Pointer container = bundle->GetTractContainer(); for(int i=0; iSize();i++) { this->PushTract(container->ElementAt(i)); } } int mitk::FiberBundle::FindTractByEndpoints(mitk::FiberBundle::DTITubeType::Pointer searchTract) { int searchNrPnts = searchTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType searchPntList = searchTract->GetPoints(); typedef mitk::FiberBundle::DTITubeType::PointType PointType; DTITubePointType searchPointFirst = searchPntList.at(0); PointType searchPos1 = searchPointFirst.GetPosition(); DTITubePointType searchPointLast = searchPntList.at(searchNrPnts-1); PointType searchPos2 = searchPointLast.GetPosition(); FiberGroupType::Pointer groupFiberBundle = this->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubePointType point_first = dtiPntList.at(0); PointType pos1 = point_first.GetPosition(); DTITubePointType point_last = dtiPntList.at(fibrNrPnts-1); PointType pos2 = point_last.GetPosition(); if( (pos1 == searchPos1 && pos2 == searchPos2) || (pos2 == searchPos1 && pos1 == searchPos2) ) { return dtiTract->GetId(); } } return -1; } mitk::FiberBundle::Pointer mitk::FiberBundle::SubstractBundle(mitk::FiberBundle::Pointer bundle) { mitk::FiberBundle::Pointer retval = mitk::FiberBundle::New(); retval->SetGeometry(this->GetGeometry()); mitk::FiberBundle::Pointer largeBundle = bundle; mitk::FiberBundle::Pointer smallBundle = this; MITK_INFO << "large children " << largeBundle->GetGroupFiberBundle()->GetNumberOfChildren() << "!="<GetNumTracts(); MITK_INFO << "small children " << smallBundle->GetGroupFiberBundle()->GetNumberOfChildren() << "!="<GetNumTracts(); if(this->GetGroupFiberBundle()->GetNumberOfChildren() > bundle->GetGroupFiberBundle()->GetNumberOfChildren()) { MITK_INFO << "this is large (" << this->GetNumTracts() << ">" << bundle->GetNumTracts() << ")"; largeBundle = this; smallBundle = bundle; } ContainerType::Pointer container = largeBundle->GetTractContainer(); int counter = 0; FiberGroupType::Pointer groupFiberBundle = largeBundle->GetGroupFiberBundle(); ChildrenListType *fiberList = groupFiberBundle->GetChildren(); MITK_INFO << "large number children " << groupFiberBundle->GetNumberOfChildren(); for(ChildrenListType::iterator itLst = fiberList->begin(); itLst != fiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } int delId = smallBundle->FindTractByEndpoints(dtiTract); if( delId == -1 ) { retval->addSingleDTITract(dtiTract); retval->PushTract(container->ElementAt(counter)); } MITK_INFO << "Counter " << counter++; } return retval; } mitk::FiberBundle::ContainerPointType mitk::FiberBundle::GetPoint(int tractIndex, int pointIndex) { if (tractIndex>=0 && tractIndex=0 && pointIndexGetElement(tractIndex)->GetElement(pointIndex); } return NULL; } int mitk::FiberBundle::GetNumTracts() { return m_TractContainer->Size(); } int mitk::FiberBundle::GetNumPoints(int tractIndex) { if ((unsigned)tractIndex>=0 && (unsigned)tractIndexSize()) { return m_TractContainer->GetElement(tractIndex)->Size(); } else { //added by igi return NULL; } } mitk::FiberBundle::ContainerTractType::Pointer mitk::FiberBundle::GetTract(int tractIndex) { ContainerTractType::Pointer out; if ((unsigned)tractIndex>0 && (unsigned)tractIndexSize()) return m_TractContainer->GetElement(tractIndex); return out; } void mitk::FiberBundle::additkStochTractContainer(itkStochTractContainerType::Pointer itkStochCont) { //for debugging only m_debugITKContainer = itkStochCont; //******************** /* transform itkStochContainer to standardized TractContainer */ for (itkStochTractContainerType::ConstIterator itCont = itkStochCont->Begin(); itCont != itkStochCont->End(); ++itCont) { // get fiber of itkContainer itkStochTractType::Pointer tract = itCont->Value(); itkStochTractType::VertexListType::ConstPointer vertexlist = tract->GetVertexList(); //init a desired containerFiber ContainerTractType::Pointer contTract = ContainerTractType::New(); //get points of fiber for( int j=0; j<(int)vertexlist->Size(); ++j) { // put the point of vertex pointList in itkContainer itkStochTractType::VertexType vertex = vertexlist->GetElement(j); //prepare for dtiPoint ContainerPointType contPnt; contPnt[0] = (float) vertex[0]; contPnt[1] = (float) vertex[1]; contPnt[2] = (float) vertex[2]; contTract->InsertElement(contTract->Size(), contPnt); /* coordinate testing*/ /*if ((float)vertex[0] == contPnt[0]) { MITK_INFO << " [OK] ... X "; }else { MITK_INFO << "[FAIL] ... itkX: " << vertex[0] << " " << contPnt[0] << "\n" ; } if ((float)vertex[1] == contPnt[1]) { MITK_INFO << " [OK] ... Y "; }else { MITK_INFO << "[FAIL] ... itkY: " << vertex[1] << " " << contPnt[1] << "\n" ; } if ((float)vertex[2] == contPnt[2]) { MITK_INFO << " [OK] ... Z " << "\n" ; MITK_INFO << " Values X Y Z: " << contPnt[0] << " " << contPnt[1] << " " << contPnt[2] << "\n"; }else { MITK_INFO << "[FAIL] ... itkZ: " << vertex[2] << " " << contPnt[2] << "\n" ; } */ } // add filled fiber to container m_TractContainer->InsertElement(m_TractContainer->Size(), contTract); } } void mitk::FiberBundle::addTractContainer( ContainerType::Pointer tractContainer ) { m_TractContainer = tractContainer; } void mitk::FiberBundle::initFiberGroup() { /* iterate through the tractContainer and store fibers in DTISpatialObjects */ for (ContainerType::ConstIterator itCont = m_TractContainer->Begin(); itCont != m_TractContainer->End(); ++itCont) { // init new dtiTube and DTITubeType::Pointer dtiTube = DTITubeType::New(); DTITubeType::PointListType list; // get current tract of container ContainerTractType::Pointer contTract = itCont->Value(); // iterate through the number of points ... use iterator, no index-output is needed anyway for(ContainerTractType::Iterator itContTrct = contTract->Begin(); itContTrct != contTract->End(); ++itContTrct) { // init DTITube point DTITubePointType p; ContainerPointType cntp = itContTrct->Value(); p.SetPosition(cntp[0], cntp[1], cntp[2]); p.SetRadius(1); mitk::FiberBundle::fiberPostprocessing_setTensorMatrix( &p ); mitk::FiberBundle::fiberPostprocessing_FA( &p ); //mitk::FiberBundle::fiberPostprocessing_setTensorMatrix( &p ); p.AddField(DTITubePointType::GA, 3); p.SetColor(1,0,0,1); list.push_back(p); } // dtiTubes dtiTube->GetProperty()->SetName("dtiTube"); dtiTube->SetId(itCont->Index()); dtiTube->SetPoints(list); m_GroupFiberBundle->AddSpatialObject(dtiTube); } } void mitk::FiberBundle::fiberPostprocessing_setTensorMatrix(DTITubePointType *dtiP) { float tMatrix[6]; tMatrix[0]=0.0f; tMatrix[1]=1.0f; tMatrix[2]=2.0f; tMatrix[3]=3.0f; tMatrix[4]=4.0f; tMatrix[5]=5.0f; dtiP->SetTensorMatrix(tMatrix); } /* this method is a HowTo method, used for debugging only */ void mitk::FiberBundle::fiberPostprocessing_setPoint(DTITubePointType *dtiP, ContainerPointType vrtx) { /* get values of variable referenced by a ponter double vtxIdx1, vtxIdx2, vtxIdx3; vtxIdx1 = * (double*) &vrtx[0]; vtxIdx2 = * (double*) &vrtx[1]; vtxIdx3 = * (double*) &vrtx[2]; dtiP->SetPosition(vtxIdx1, vtxIdx2, vtxIdx3); */ dtiP->SetPosition(vrtx[0], vrtx[1], vrtx[2]); } void mitk::FiberBundle::fiberPostprocessing_FA(DTITubePointType *dtiP) { debug_PrototypeCounter ++; float valFA; if (debug_PrototypeCounter % 10 < 5) { valFA = 1.0; } else if (debug_PrototypeCounter % 10 == 7) { valFA = 0.3; } else if (debug_PrototypeCounter % 10 == 8) { valFA = 0; } else { valFA = 0.5; } dtiP->AddField(DTITubePointType::FA, valFA); } /* methods for high speed perfoermance dispay or live-monitoring of fiber results */ void mitk::FiberBundle::addContainer4speedDisplay(ContainerType::Pointer speedTractContainer) { } void mitk::FiberBundle::addSingleDTITract(mitk::FiberBundle::DTITubeType::Pointer dtiFbrTrct) { //MITK_INFO << " start addSingleDTITract(): " << m_GroupFiberBundle->GetNumberOfChildren(); m_GroupFiberBundle->AddSpatialObject(dtiFbrTrct); //MITK_INFO << "end addSingleDTITract(): " << m_GroupFiberBundle->GetNumberOfChildren(); } mitk::FiberBundle::FiberGroupType::Pointer mitk::FiberBundle::getGroupFiberBundle() { return m_GroupFiberBundle; } std::vector mitk::FiberBundle::getAllIDsInFiberBundle() { std::vector allFBIds; FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } allFBIds.push_back(dtiTract->GetId()); } return allFBIds; } mitk::FiberBundle::Pointer mitk::FiberBundle::extractFibersById(std::vector idSet) { mitk::FiberBundle::Pointer resultingFibers = mitk::FiberBundle::New(); resultingFibers->SetGeometry(this->GetGeometry()); resultingFibers->SetBounds(this->GetBounds()); //get Fiber by ID //get childrenList //compare if current FiberID is in idSet FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); MITK_INFO << "writing fibers into datastructure:...."; for (int cg=0; cgPushTract( m_TractContainer->GetElement(trctId) ); } MITK_INFO << "init new fiberBundle..."; resultingFibers->initFiberGroup(); MITK_INFO << "init new fiberBundle [DONE]"; /* for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << "DTI Tract is NULL!!!!! omg"; continue; } // MITK_INFO << "current DTI tract id: " << dtiTract->GetId(); std::vector::iterator retFibers = find(idSet.begin(), idSet.end(), dtiTract->GetId()); if (retFibers != idSet.end()) { //MITK_INFO << "Fiber and ID equal: "; DTITubeType::Pointer copyDTITract = this->copySingleDTITract(dtiTract); MITK_INFO << "fibercontainer before adding new tract" << resultingFibers->GetNumTracts(); resultingFibers->addSingleDTITract(copyDTITract); MITK_INFO << "fibercontainer after adding new tract" << resultingFibers->GetNumTracts(); } //else { // MITK_INFO << "Fiber and ID not ident!"; //} //std::set::iterator retFibers //retFibers = idSet.find(dtiTract->GetId()); } */ return resultingFibers; } /* extract fibers using planar Figures */ //mitk::FiberBundle::Pointer mitk::FiberBundle::extractFibersPF(mitk::PlanarFigure::Pointer pf) std::vector mitk::FiberBundle::extractFibersByPF(mitk::PlanarFigure::Pointer pf, std::vector* smaller_set) { - // if incoming pf is a pfc mitk::PlanarFigureComposite::Pointer pfcomp= dynamic_cast(pf.GetPointer()); if (!pfcomp.IsNull()) { //PFC - - switch (pfcomp->getOperationType()) { case 0: { //AND std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::vector tmpChild = childResults; for (int i=1; igetNumberOfChildren(); ++i) { tmpChild = extractFibersByPF(pfcomp->getChildAt(i),&tmpChild); } std::vector AND_Assamblage(tmpChild.begin(), tmpChild.end()); return AND_Assamblage; } case 1: { //OR std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::sort(childResults.begin(), childResults.end()); std::vector tmp_container(m_TractContainer->Size()); std::vector::iterator end; for (int i=1; igetNumberOfChildren(); ++i) { std::vector tmpChild = extractFibersByPF(pfcomp->getChildAt(i), smaller_set); sort(tmpChild.begin(), tmpChild.end()); end = std::set_union(childResults.begin(), childResults.end(), tmpChild.begin(), tmpChild.end(), tmp_container.begin() ); childResults.assign(tmp_container.begin(), end); } std::vector OR_Assamblage(childResults.begin(), childResults.end()); return OR_Assamblage; } case 2: { //NOT // FIRST AN AND OPERATION std::vector childResults = this->extractFibersByPF(pfcomp->getChildAt(0), smaller_set); std::sort(childResults.begin(), childResults.end()); std::vector tmpChild = childResults; for (int i=1; igetNumberOfChildren(); ++i) { tmpChild = extractFibersByPF(pfcomp->getChildAt(i),&tmpChild); } std::vector AND_Assamblage(tmpChild.begin(), tmpChild.end()); // get IDs of interesting fibers std::vector interesting_fibers; if(!smaller_set) interesting_fibers = this->getAllIDsInFiberBundle(); else interesting_fibers.assign(smaller_set->begin(), smaller_set->end()); std::sort(interesting_fibers.begin(), interesting_fibers.end()); // all interesting fibers that are not in the AND assemblage std::vector tmp_not(interesting_fibers.size()); std::vector::iterator end; end = std::set_difference(interesting_fibers.begin(), interesting_fibers.end(), AND_Assamblage.begin(), AND_Assamblage.end(), tmp_not.begin() ); std::vector NOT_Assamblage(tmp_not.begin(),end); return NOT_Assamblage; } default: MITK_INFO << "we have an UNDEFINED composition... ERROR" ; break; - - } - } else { mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { //MITK_INFO << "We have a circle :-) " ; int cntGaps = 0; //init output FiberBundle mitk::FiberBundle::Pointer FB_Clipped = mitk::FiberBundle::New(); FB_Clipped->SetGeometry(this->GetGeometry()); //get geometry containing the plane which we need to calculate the xrossingPoints mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); std::vector XingPoints; std::vector fiberIDs; //################################################################# //############### Find Gap, FrontFace BackFace #################### //################################################################# //get fibercontainer and iterate through the fibers FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); //extract single fibers ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); // iterate through each single tract //int cntFibId = -1; for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { //MITK_INFO << "***************** NEW FIBER *********************"; //cntFibId++; itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " could not cast groupFiberBundle child into dtiTract!... LEVEL 4 ERROR"; continue; } if (smaller_set && std::find(smaller_set->begin(), smaller_set->end(), dtiTract->GetId())==smaller_set->end()) continue; //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); // if one fiber is represented by just one point.... // check if this point is on the plane if (fibrNrPnts <= 0) { MITK_INFO << "HyperERROR in mitkFiberBundle.cpp, No point in fiber....check ur algorithm:"; continue; } /* for finding a gap we need to have knowledge of the previous normal * be aware that there can be more than 1 gaps! */ int prevPntFacing = -999999; int currPntFacing = -999999; //double prevFacing = -99999999099; mitk::Point3D prevFiberPntmm; for(int i=0; iGetGeometry()->IndexToWorld(tmpFiberVec, currentFiberPntmm); double faceing = pfgeometry->SignedDistance(currentFiberPntmm); //MITK_INFO << "FacingOutput: " << faceing; /////////////////////////////////////// if (faceing < 0) { //backface currPntFacing = TRACTPOINT_BACKFACE; //MITK_INFO << "is BACKFACE" << currentFiberPntmm ; } else if (faceing > 0) { //frontface currPntFacing = TRACTPOINT_FRNTFACE; // MITK_INFO << "is FRONTFACE" << currentFiberPntmm ; } else if (faceing == 0) { //onplane currPntFacing = TRACTPOINT_ON_PLANE; //MITK_INFO << "is on PLANE" << currentFiberPntmm ; } //////////////////////////////////////// if (currPntFacing == TRACTPOINT_ON_PLANE) { //strike, //calculate distance //TODO SOURCE THIS CONTROLSTRUCTURE OUT if(isPointInSelection(tmpFiberVec,pf)) { DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); //MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); FB_Clipped->addSingleDTITract(copyDTITract); } } else { // Point is BACKFACE or FRONTFACE if (i > 0) { //check if there is a gap between previous and current bool isGap = checkForGap(currPntFacing, prevPntFacing); if (isGap == true) { ++cntGaps; // mitk::Vector3D LineDirection; LineDirection[0] = currentFiberPntmm[0] - prevFiberPntmm[0]; LineDirection[1] = currentFiberPntmm[1] - prevFiberPntmm[1]; LineDirection[2] = currentFiberPntmm[2] - prevFiberPntmm[2]; mitk::Line3D Xingline( prevFiberPntmm, LineDirection ); mitk::Point3D intersectionPoint; Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Vector3D lineDirection = Xingline.GetDirection(); lineDirection.Normalize(); double t = planeNormal * lineDirection; if ( fabs( t ) < eps ) { } Vector3D diff; diff = planeGeometry->GetOrigin() - Xingline.GetPoint(); t = ( planeNormal * diff ) / t; intersectionPoint = Xingline.GetPoint() + lineDirection * t; // bool successXing = planeGeometry->IntersectionPoint( Xingline, intersectionPoint ); //mitk::Point3D intersectionPointmm; //planeGeometry->IndexToWorld(intersectionPoint,intersectionPointmm ); // MITK_INFO << "PlaneIntersectionPoint: " << intersectionPoint; if (false) { MITK_INFO << " ERROR CALCULATING INTERSECTION POINT.....should not happen!! "; } //TODO more nice if this if is outside... bool pntInROI = isPointInSelection(intersectionPoint,pf); if(pntInROI) { // MITK_INFO << "POINT ALSO in ROI"; // MITK_INFO << "GroupFB extract before copy new object. of Children: " << fiberGroup->GetNumberOfChildren(); /* dtiTubeSpatial::Pointer can not occur in 2 GroupSpatialObjects, therefore we have to copy the whole dtiTract of current List and add the copy to the desired FiberBundle */ // DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); // MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); //FB_Clipped->addSingleDTITract(copyDTITract); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); //MITK_INFO << "DTI Tract ID: " << dtiTract->GetId(); // MITK_INFO << "size of Vector before pushing: " << fiberIDs.size(); fiberIDs.push_back(dtiTract->GetId()); // MITK_INFO << "size of Vector after pushing: " << fiberIDs.size(); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); break; } } // MITK_INFO << "---no gap---"; } //endif i>0 } //endif Facing // MITK_INFO << "GroupFB extract end Facing, NR. of Children: " << fiberGroup->GetNumberOfChildren(); //update point flag prevPntFacing = currPntFacing; prevFiberPntmm = currentFiberPntmm; } //end for fiberPoints //MITK_INFO ;<< "GroupFB extract end of single tract, NR. of Children: " << fiberGroup->GetNumberOfChildren(); } //end for fiberTracts // MITK_INFO << "GroupFB extract end of iterating through fiberBundle, NR. of Children: " << fiberGroup->GetNumberOfChildren(); // MITK_INFO << "selected " << fiberIDs.size() << " fibers " << " | counted gaps: " << cntGaps; return fiberIDs; } else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { //MITK_INFO << "We have a polygon :-) " ; int cntGaps = 0; //init output FiberBundle mitk::FiberBundle::Pointer FB_Clipped = mitk::FiberBundle::New(); FB_Clipped->SetGeometry(this->GetGeometry()); //get geometry containing the plane which we need to calculate the xrossingPoints mitk::Geometry2D::ConstPointer pfgeometry = pf->GetGeometry2D(); const mitk::PlaneGeometry* planeGeometry = dynamic_cast (pfgeometry.GetPointer()); std::vector XingPoints; std::vector fiberIDs; //################################################################# //############### Find Gap, FrontFace BackFace #################### //################################################################# //get fibercontainer and iterate through the fibers FiberGroupType::Pointer fiberGroup = this->getGroupFiberBundle(); //extract single fibers ChildrenListType *FiberList; FiberList = fiberGroup->GetChildren(); int nrFibrs = fiberGroup->GetNumberOfChildren(); // iterate through each single tract int cntFib = 1; for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { if (cntFib % 500 == 0) { MITK_INFO << "================\n prosessed fibers: " << cntFib << " of " << nrFibrs;; } ++cntFib; //MITK_INFO << "***************** NEW FIBER *********************"; //cntFibId++; itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " could not cast groupFiberBundle child into dtiTract!... LEVEL 4 ERROR"; continue; } if (smaller_set && std::find(smaller_set->begin(), smaller_set->end(), dtiTract->GetId())==smaller_set->end()) continue; //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); // if one fiber is represented by just one point.... // check if this point is on the plane if (fibrNrPnts <= 0) { MITK_INFO << "HyperERROR in mitkFiberBundle.cpp, No point in fiber....check ur algorithm:"; continue; } /* for finding a gap we need to have knowledge of the previous normal * be aware that there can be more than 1 gaps! */ int prevPntFacing = -999999; int currPntFacing = -999999; //double prevFacing = -99999999099; mitk::Point3D prevFiberPntmm; for(int i=0; iGetGeometry()->IndexToWorld(tmpFiberVec, currentFiberPntmm); double faceing = pfgeometry->SignedDistance(currentFiberPntmm); //MITK_INFO << "FacingOutput: " << faceing; /////////////////////////////////////// if (faceing < 0) { //backface currPntFacing = TRACTPOINT_BACKFACE; //MITK_INFO << "is BACKFACE" << currentFiberPntmm ; } else if (faceing > 0) { //frontface currPntFacing = TRACTPOINT_FRNTFACE; // MITK_INFO << "is FRONTFACE" << currentFiberPntmm ; } else if (faceing == 0) { //onplane currPntFacing = TRACTPOINT_ON_PLANE; //MITK_INFO << "is on PLANE" << currentFiberPntmm ; } //////////////////////////////////////// if (currPntFacing == TRACTPOINT_ON_PLANE) { //strike, //calculate distance //TODO SOURCE THIS CONTROLSTRUCTURE OUT if(isPointInSelection(tmpFiberVec,pf)) { DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); //MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); FB_Clipped->addSingleDTITract(copyDTITract); } } else { // Point is BACKFACE or FRONTFACE if (i > 0) { //check if there is a gap between previous and current bool isGap = checkForGap(currPntFacing, prevPntFacing); if (isGap == true) { ++cntGaps; // mitk::Vector3D LineDirection; LineDirection[0] = currentFiberPntmm[0] - prevFiberPntmm[0]; LineDirection[1] = currentFiberPntmm[1] - prevFiberPntmm[1]; LineDirection[2] = currentFiberPntmm[2] - prevFiberPntmm[2]; mitk::Line3D Xingline( prevFiberPntmm, LineDirection ); mitk::Point3D intersectionPoint; Vector3D planeNormal = planeGeometry->GetNormal(); planeNormal.Normalize(); Vector3D lineDirection = Xingline.GetDirection(); lineDirection.Normalize(); double t = planeNormal * lineDirection; if ( fabs( t ) < eps ) { } Vector3D diff; diff = planeGeometry->GetOrigin() - Xingline.GetPoint(); t = ( planeNormal * diff ) / t; intersectionPoint = Xingline.GetPoint() + lineDirection * t; // bool successXing = planeGeometry->IntersectionPoint( Xingline, intersectionPoint ); //mitk::Point3D intersectionPointmm; //planeGeometry->IndexToWorld(intersectionPoint,intersectionPointmm ); // MITK_INFO << "PlaneIntersectionPoint: " << intersectionPoint; if (false) { MITK_INFO << " ERROR CALCULATING INTERSECTION POINT.....should not happen!! "; } //TODO more nice if this if is outside... bool pntInROI = isPointInSelection(intersectionPoint,pf); if(pntInROI) { // MITK_INFO << "POINT ALSO in ROI"; // MITK_INFO << "GroupFB extract before copy new object. of Children: " << fiberGroup->GetNumberOfChildren(); /* dtiTubeSpatial::Pointer can not occur in 2 GroupSpatialObjects, therefore we have to copy the whole dtiTract of current List and add the copy to the desired FiberBundle */ // DTITubeType::Pointer copyDTITract = copySingleDTITract(dtiTract); // MITK_INFO << "GroupFB extract after copy of Children: " << fiberGroup->GetNumberOfChildren(); //FB_Clipped->addSingleDTITract(copyDTITract); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); //MITK_INFO << "DTI Tract ID: " << dtiTract->GetId(); // MITK_INFO << "size of Vector before pushing: " << fiberIDs.size(); fiberIDs.push_back(dtiTract->GetId()); // MITK_INFO << "size of Vector after pushing: " << fiberIDs.size(); //MITK_INFO << "GroupFB extract after adding dtiTract to now FB NR. of Children: " << fiberGroup->GetNumberOfChildren(); break; } } // MITK_INFO << "---no gap---"; } //endif i>0 } //endif Facing // MITK_INFO << "GroupFB extract end Facing, NR. of Children: " << fiberGroup->GetNumberOfChildren(); //update point flag prevPntFacing = currPntFacing; prevFiberPntmm = currentFiberPntmm; } //end for fiberPoints //MITK_INFO ;<< "GroupFB extract end of single tract, NR. of Children: " << fiberGroup->GetNumberOfChildren(); } //end for fiberTracts // MITK_INFO << "GroupFB extract end of iterating through fiberBundle, NR. of Children: " << fiberGroup->GetNumberOfChildren(); // MITK_INFO << "selected " << fiberIDs.size() << " fibers " << " | counted gaps: " << cntGaps; return fiberIDs; } else { - MITK_INFO << "[ERROR] unhandled PlanarFigureType found!"; } - } - - - - - - - - - + return std::vector(); } mitk::FiberBundle::DTITubeType::Pointer mitk::FiberBundle::copySingleDTITract(mitk::FiberBundle::DTITubeType::Pointer currentDtiFiber) { DTITubeType::Pointer newCopyDtiFiber = DTITubeType::New(); //*** get ID newCopyDtiFiber->SetId( currentDtiFiber->GetId() ); //*** get points DTITubeType::PointListType list; //get list of dtiPoints int fibrNrPnts = currentDtiFiber->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = currentDtiFiber->GetPoints(); for(int i=0; iSetPoints(list); std::string dtiname = currentDtiFiber->GetProperty()->GetName(); newCopyDtiFiber->GetProperty()->SetName(dtiname.c_str()); return newCopyDtiFiber; } /* This Method checks * To recognize a gap between the 2 points, the previous must differ from the current * but if the previous is on the plane and the current one not, then mark this situation as no gap * if both, previous and current are on plane, you'll never jump into this Method */ bool mitk::FiberBundle::checkForGap(int crntPntFacing, int prevPntFacing) { bool isGap = false; if (prevPntFacing != TRACTPOINT_ON_PLANE && crntPntFacing != prevPntFacing) { isGap = true; } else if (prevPntFacing == TRACTPOINT_ON_PLANE && crntPntFacing == TRACTPOINT_ON_PLANE) { MITK_INFO << "###########################################"; MITK_INFO << "$$$ HYPER ERROR, LOGIC MALFUNCTION!! previous point and current point in a fiber are recognized as a potential GAP! THIS IS NOT ALLOWED $$$"; MITK_INFO << "###########################################"; } return isGap; } mitk::Point3D mitk::FiberBundle::calculateCrossingPoint(mitk::Point3D pntFrnt, mitk::Point3D pntbck, mitk::PlanarFigure::Pointer pf) { mitk::Point3D pntXing; //################################################################# //######### Calculate intersection of plane and fiber ############# //################################################################# // transform in space :-) // y = k*x +d // k = (y1 - y0)/(x1 - x0) // d = ok // z adoption, take xy ratio to plane intersection and adopt it to z coordinate // z_intersx = (x1 - intersX)/(x1 - x0) * (z1 - z0) + z1 - double y; double k; //slope - double d; double x0 = pntFrnt[0]; double y0 = pntFrnt[1]; double z0 = pntFrnt[2]; double x1 = pntbck[0]; double y1 = pntbck[1]; double z1 = pntbck[2]; k = (y1 - y0) / (x1 - x0); // if slope == 0 then leave y as it is, change x // if slope == 1 then leave x as it is, change y // if z of p0 and p1 is the same, just take z /* mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { MITK_INFO << "We have a circle :-) " ; //controlpoint 1 is middlepoint //controlpoint 2 is radiuspoint mitk::Vector3D V1w = pf->GetWorldControlPoint(0); //centerPoint mitk::Vector3D V2w = pf->GetWorldControlPoint(1); //radiusPoint mitk::Vector3D V1; mitk::Vector3D V2; this->GetGeometry()->WorldToIndex(V1w, V1); this->GetGeometry()->WorldToIndex(V2w, V2); //calculate distance between those 2 and mitk::Point3D distV; distV = V2 - V1; distV[0] = sqrt( pow(distV[0], 2.0) ); distV[1] = sqrt( pow(distV[1], 2.0) ); distV[2] = sqrt( pow(distV[2], 2.0) ); mitk::Point3D distPnt; distPnt = pnt3D - V1; distPnt[0] = sqrt( pow(distPnt[0], 2.0) ); distPnt[1] = sqrt( pow(distPnt[1], 2.0) ); distPnt[2] = sqrt( pow(distPnt[2], 2.0) ); if ( (distPnt <= distV) ) { pntIsInside = true; } return pntIsInside; //compare the result to the distance of all points an a fiber } else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { MITK_INFO << "We have a polygon :-) " ; } */ return pntXing; } bool mitk::FiberBundle::isPointInSelection(mitk::Point3D pnt3D, mitk::PlanarFigure::Pointer pf) { /* TODO needs to be redesigned.... each time because in planarPolygonsection VTK object will be initialized for each point!...PERFORMANCE LACK!!!!!!! */ - //calculate distances mitk::PlanarCircle::Pointer circleName = mitk::PlanarCircle::New(); mitk::PlanarRectangle::Pointer rectName = mitk::PlanarRectangle::New(); mitk::PlanarPolygon::Pointer polyName = mitk::PlanarPolygon::New(); if (pf->GetNameOfClass() == circleName->GetNameOfClass() ) { //MITK_INFO << "We have a circle :-) " ; //controlpoint 1 is middlepoint //controlpoint 2 is radiuspoint mitk::Point3D V1w = pf->GetWorldControlPoint(0); //centerPoint mitk::Point3D V2w = pf->GetWorldControlPoint(1); //radiusPoint mitk::Vector3D V1; mitk::Vector3D V2; // this->GetGeometry()->WorldToIndex(V1w, V1); // this->GetGeometry()->WorldToIndex(V2w, V2); //calculate distance between those 2 and double distPF; distPF = sqrt((double) (V2w[0] - V1w[0]) * (V2w[0] - V1w[0]) + (V2w[1] - V1w[1]) * (V2w[1] - V1w[1]) + (V2w[2] - V1w[2]) * (V2w[2] - V1w[2])); double XdistPnt = sqrt((double) (pnt3D[0] - V1w[0]) * (pnt3D[0] - V1w[0]) + (pnt3D[1] - V1w[1]) * (pnt3D[1] - V1w[1]) + (pnt3D[2] - V1w[2]) * (pnt3D[2] - V1w[2])) ; - - if ( (distPF > XdistPnt) ) { return true; - } return false; - //compare the result to the distance of all points an a fiber - - } - - - else if (pf->GetNameOfClass() == rectName->GetNameOfClass() ){ MITK_INFO << "We have a rectangle :-) " ; - } else if (pf->GetNameOfClass() == polyName->GetNameOfClass() ) { - //create vtkPolygon using controlpoints from planarFigure polygon vtkSmartPointer polygonVtk = vtkPolygon::New(); - //get the control points from pf and insert them to vtkPolygon unsigned int nrCtrlPnts = pf->GetNumberOfControlPoints(); // MITK_INFO << "We have a polygon with " << nrCtrlPnts << " controlpoints: " ; for (int i=0; iGetPoints()->InsertNextPoint((double)pf->GetWorldControlPoint(i)[0], (double)pf->GetWorldControlPoint(i)[1], (double)pf->GetWorldControlPoint(i)[2] ); - - } //prepare everything for using pointInPolygon function double n[3]; polygonVtk->ComputeNormal(polygonVtk->GetPoints()->GetNumberOfPoints(), static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), n); double bounds[6]; polygonVtk->GetPoints()->GetBounds(bounds); double checkIn[3] = {pnt3D[0], pnt3D[1], pnt3D[2]}; int isInPolygon = polygonVtk->PointInPolygon(checkIn, polygonVtk->GetPoints()->GetNumberOfPoints() , static_cast(polygonVtk->GetPoints()->GetData()->GetVoidPointer(0)), bounds, n); // MITK_INFO << "======IsPointOnPolygon:========\n" << isInPolygon << "\n ======================== "; polygonVtk->Delete(); if (isInPolygon == 1) { // MITK_INFO << "return true"; return true; - - } else if (isInPolygon == 0) { // MITK_INFO << "return false"; return false; - } else { - MITK_INFO << "&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*& \n YOUR DRAWN POLYGON DOES IS DEGENERATED AND NOT ACCEPTED \n DRAW A NEW ONE!! HAI CAPITO \n &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&"; } - - - - - } - + return false; } void mitk::FiberBundle::debug_members() { /* Debug Workflow description * Test1: check if both, groupSpatialObject and Tract container have the same amount of fiberTracts * Test2: check if points in tracts contain the same coordinates * next... to be continued */ /* ######### TEST 1 START ######### */ //************************************* MITK_INFO << " ############### \n *** TEST Equal Amount of Fibers *** \n "; unsigned int groupEls = m_GroupFiberBundle->GetNumberOfChildren(); unsigned int contEls = m_TractContainer->Size(); unsigned int itkcontEls = m_debugITKContainer->Size(); if (groupEls == contEls && contEls == itkcontEls) { MITK_INFO << "[OK] .... Test1 passed. # of Fibers: " << groupEls << " \n ******************** "; } else { MITK_INFO << "[FAIL]: Container and FiberGroup do not contain same amount of fibers! \n "; // MITK_INFO << " Container # of Fibers: " << contEls << " | FiberBundle # of Fibers: " << groupEls << "\n"; MITK_INFO << " # of Fibers m_Cont: " << contEls << " | GroupFibers: " << groupEls << " | ITKCont: " << itkcontEls << "\n"; } /* ######### TEST 1 END ######### */ //*********************************** /* ######### TEST 2 START ######### */ //************************************* /* iterate through itkcontainer*/ itkStochTractContainerType::ConstIterator itITKCnt; itITKCnt = m_debugITKContainer->Begin(); /* extract DTIFiberTracts of the GroupFiberBundle Object */ // all smartPointers to fibers stored in in a ChildrenList ChildrenListType * FiberList; FiberList = m_GroupFiberBundle->GetChildren(); /* iterate through container, itkcontainer groupFiberBundle in one iteration step */ ChildrenListType::iterator itLst; //STL "list" itself provides no index output of current iteration step. itLst = FiberList->begin(); ContainerType::ConstIterator vecIter; for ( vecIter = m_TractContainer->Begin(); vecIter != m_TractContainer->End(); vecIter++ ) { unsigned int itIdx = vecIter->Index(); MITK_INFO << "FiberIteration: " << itIdx << "\n" ; //get single tract of container ContainerTractType::Pointer contTract = vecIter->Value(); int contNrPnts = contTract->Size(); //get singel tract of itkContainer itkStochTractType::Pointer itkcontTract = itITKCnt->Value(); itkStochTractType::VertexListType::ConstPointer itkcontVrtx = itkcontTract->GetVertexList(); int itkcontNrPnts = itkcontVrtx->Size(); /* lists output is SpatialObject, we know we have DTITubeSpacialObjects dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() */ itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; DTITubeType::Pointer dtiTract = dynamic_cast (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { MITK_INFO << " ############### *** ERRROR *** ############### \n ############### *** ERRROR *** ############### \n ############### *** ERRROR *** ############### \n "; return; } //get points of tract int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); MITK_INFO << " ############### \n *** TEST Equal Amount of Points in Tract *** \n "; if (contNrPnts == itkcontNrPnts && itkcontNrPnts == fibrNrPnts) { MITK_INFO << "[OK] .... Test2 passed. # of Points in fiber: " << fibrNrPnts << " \n ******************** "; } else { MITK_INFO << "[FAIL]: Tracts do not contain same amount of points! \n "; MITK_INFO << " # of Points m_Cont: " << contNrPnts << " | GroupFibers: " << fibrNrPnts << " | ITKCont: " << itkcontNrPnts << "\n"; } //use for()loop with index instead of iterator cuz of accessing more elements, std vectors provide no index output for(int ip=0; ipGetElement(ip); //get point from itkStochContainer itkStochTractType::VertexType itkPnt = itkcontVrtx->GetElement(ip); //get point from dtiGroup DTITubePointType tmpDtiPnt = dtiPntList.at(ip); DTITubePointType::PointType dtiPoint = tmpDtiPnt.GetPosition(); if (tmpcontPnt[0] == (float)itkPnt[0] && (float)itkPnt[0] == (float)dtiPoint[0]) { MITK_INFO << "TractCont | ITKCont | DTIGroup X: " << tmpcontPnt[0] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup X: " << tmpcontPnt[0] << " " << itkPnt[0] << " " << dtiPoint[0] << "...TEST ##### [FAIL] \n"; } if (tmpcontPnt[1] == (float)itkPnt[1] && (float)itkPnt[1] == (float)dtiPoint[1]) { MITK_INFO << "TractCont | ITKCont | DTIGroup Y: " << tmpcontPnt[1] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup Y: " << tmpcontPnt[1] << " " << itkPnt[1] << " " << dtiPoint[1] << "\n"; } if (tmpcontPnt[2] == (float)itkPnt[2] && (float)itkPnt[2] == (float)dtiPoint[2]) { MITK_INFO << "TractCont | ITKCont | DTIGroup Z: " << tmpcontPnt[2] << "...TEST [OK] " << "\n"; }else{ MITK_INFO << "TractCont | ITKCont | DTIGroup Z: " << tmpcontPnt[2] << " " << itkPnt[2] << " " << dtiPoint[2] << "\n"; } } ++itITKCnt; ++itLst; } } vtkSmartPointer mitk::FiberBundle::GeneratePolydata() { MITK_INFO << "writing polydata"; //extractn single fibers //in the groupFiberBundle all smartPointers to single fibers are stored in in a ChildrenList mitk::FiberBundle::ChildrenListType * FiberList; FiberList = this->m_GroupFiberBundle->GetChildren(); /* ######## FIBER PREPARATION END ######### */ /* ######## VTK FIBER REPRESENTATION ######## */ //create a vtkPoints object and store the all the brainFiber points in it vtkSmartPointer vtkpoints = vtkPoints::New(); //in vtkcells all polylines are stored, actually all id's of them are stored vtkSmartPointer vtkcells = vtkCellArray::New(); //in some cases a fiber includes just 1 point, so put it in here vtkSmartPointer vtkVrtxs = vtkCellArray::New(); //colors and alpha value for each single point, RGBA = 4 components vtkSmartPointer colorsT = vtkUnsignedCharArray::New(); colorsT->SetNumberOfComponents(4); colorsT->SetName("ColorValues"); vtkSmartPointer faColors = vtkDoubleArray::New(); faColors->SetName("FaColors"); //vtkDoubleArray *tubeRadius = vtkDoubleArray::New(); //tubeRadius->SetName("TubeRadius"); // iterate through FiberList for(mitk::FiberBundle::ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++itLst) { //all points are stored in one vtkpoints list, soooooooo that the lines find their point id to start and end we need some kind of helper index who monitors the current ids for a polyline unsigned long pntIdxHelper = vtkpoints->GetNumberOfPoints(); // lists output is SpatialObject, we know we have DTITubeSpacialObjects // dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; mitk::FiberBundle::DTITubeType::Pointer dtiTract = dynamic_cast< mitk::FiberBundle::DTITubeType * > (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { return NULL; } //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); mitk::FiberBundle::DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); //create a new polyline for a dtiTract //smartpointer vtkSmartPointer polyLine = vtkPolyLine::New(); polyLine->GetPointIds()->SetNumberOfIds(fibrNrPnts); unsigned char rgba[4] = {255,255,255,255}; //tubeRadius->SetNumberOfTuples(fibrNrPnts); //double tbradius = 1;//default value for radius if (fibrNrPnts <= 0) { //this should never occour! but who knows MITK_INFO << "HyperERROR in fiberBundleMapper3D.cpp ...no point in fiberBundle!!! .. check ur trackingAlgorithm"; continue; } for (int i=0; iGetGeometry()->IndexToWorld(indexPnt, worldPnt); double worldFbrPnt[3] = {worldPnt[0], worldPnt[1], worldPnt[2]}; vtkpoints->InsertNextPoint(worldFbrPnt); // tubeRadius->SetTuple1(i,tbradius); //tuple with 1 argument if (fibrNrPnts == 1) { // if there ist just 1 point in a fiber...wtf, but however represent it as a point vtkSmartPointer vrtx = vtkVertex::New(); vrtx->GetPointIds()->SetNumberOfIds(1); vrtx->GetPointIds()->SetId(i,i+pntIdxHelper); colorsT->InsertNextTupleValue(rgba); vtkVrtxs->InsertNextCell(vrtx); } else { polyLine->GetPointIds()->SetId(i,i+pntIdxHelper); //colorcoding orientation based if (i0) { //nimm nur diff1 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i+1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); //double nxttmpvtkPnt[3] = {nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]}; vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if(i==0) { //explicit handling of startpoint of line //nimm nur diff1 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i+1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); //double nxttmpvtkPnt[3] = {nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]}; vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } else if(i==fibrNrPnts) { // nimm nur diff2 mitk::FiberBundle::DTITubePointType nxttmpFiberPntLst = dtiPntList.at(i-1); mitk::FiberBundle::DTITubePointType::PointType nxttmpFiberPnt = nxttmpFiberPntLst.GetPosition(); vnl_vector_fixed< double, 3 > tmpPntvtk((double)tmpvtkPnt[0], (double)tmpvtkPnt[1],(double)tmpvtkPnt[2]); vnl_vector_fixed< double, 3 > nxttmpPntvtk(nxttmpFiberPnt[0], nxttmpFiberPnt[1], nxttmpFiberPnt[2]); vnl_vector_fixed< double, 3 > diff; diff = tmpPntvtk - nxttmpPntvtk; diff.normalize(); rgba[0] = (unsigned char) (255.0 * std::abs(diff[0])); rgba[1] = (unsigned char) (255.0 * std::abs(diff[1])); rgba[2] = (unsigned char) (255.0 * std::abs(diff[2])); rgba[3] = (unsigned char) (255.0); } colorsT->InsertNextTupleValue(rgba); //get FA value float faVal = tmpFiberPntLst.GetField(mitk::FiberBundle::DTITubePointType::FA); //use insertNextValue cuz FA Values are reperesented as a single number (1 Tuple containing 1 parameter) faColors->InsertNextValue((double) faVal); } } vtkcells->InsertNextCell(polyLine); } //vtkcells->InitTraversal(); // Put points and lines together in one polyData structure m_PolyData = vtkPolyData::New(); m_PolyData->SetPoints(vtkpoints); m_PolyData->SetLines(vtkcells); if (vtkVrtxs->GetSize() > 0) { m_PolyData->SetVerts(vtkVrtxs); } m_PolyData->GetPointData()->AddArray(colorsT); m_PolyData->GetPointData()->AddArray(faColors); return m_PolyData; } /* NECESSARY IMPLEMENTATION OF SUPERCLASS METHODS */ void mitk::FiberBundle::UpdateOutputInformation() { } void mitk::FiberBundle::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::FiberBundle::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::FiberBundle::VerifyRequestedRegion() { return true; } void mitk::FiberBundle::SetRequestedRegion( itk::DataObject *data ) { } /* TUTORIAL INSERT POINTS / FIBERS to TRACTCONTAINER */ // points and vectors do not need to be initiated but itkVectorContainer /*ContainerPointType pnt1; pnt1[0] = 1.0; pnt1[1] = 2.0; pnt1[2] = 3.0; ContainerPointType pnt2; pnt2[0] = 4.0; pnt2[1] = 5.0; pnt2[2] = 6.0; ContainerTractType tract1; tract1.push_back(pnt1); tract1.push_back(pnt2); ContainerType::Pointer testContainer = ContainerType::New(); unsigned int freeIdx = testContainer->Size(); MITK_INFO << freeIdx << "\n"; testContainer->InsertElement(freeIdx, tract1); //iterate through all fibers stored in container for(ContainerType::ConstIterator itCont = testContainer->Begin(); itCont != testContainer->End(); itCont++) { //get single tract ContainerTractType tmp_fiber = itCont->Value(); // MITK_INFO << tmp_fiber << "\n"; //iterate through all points within a fibertract for(ContainerTractType::iterator itPnt = tmp_fiber.begin(); itPnt != tmp_fiber.end(); ++itPnt) { // get single point with its coordinates ContainerPointType tmp_pntEx = *itPnt; MITK_INFO << tmp_pntEx[0] << "\n"; MITK_INFO << tmp_pntEx[1] << "\n"; MITK_INFO << tmp_pntEx[2] << "\n"; } } ################### DTI FIBERs TUTORIAL ########################### TUTORIAL HOW TO READ POINTS / FIBERS from DTIGroupSpatialObjectContainer assume our dti fibers are stored in m_GroupFiberBundle // all smartPointers to fibers stored in in a ChildrenList ChildrenListType * FiberList; FiberList = m_GroupFiberBundle->GetChildren(); // iterate through container, itkcontainer groupFiberBundle in one iteration step for(ChildrenListType::iterator itLst = FiberList->begin(); itLst != FiberList->end(); ++FiberList) { // lists output is SpatialObject, we know we have DTITubeSpacialObjects // dynamic cast only likes pointers, no smartpointers, so each dsmartpointer has membermethod .GetPointer() itk::SpatialObject<3>::Pointer tmp_fbr; tmp_fbr = *itLst; DTITubeType::Pointer dtiTract = dynamic_cast (tmp_fbr.GetPointer()); if (dtiTract.IsNull()) { return; } //get list of points int fibrNrPnts = dtiTract->GetNumberOfPoints(); DTITubeType::PointListType dtiPntList = dtiTract->GetPoints(); } */ diff --git a/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp b/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp index f9bc87b82d..4058b1610f 100644 --- a/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp +++ b/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkNrrdTbssRoiImageReader.cpp @@ -1,357 +1,357 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkNrrdTbssRoiReader_cpp #define __mitkNrrdTbssRoiReader_cpp #include "mitkNrrdTbssRoiImageReader.h" #include "itkImageFileReader.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include "itkNiftiImageIO.h" #include #include #include #include "itksys/SystemTools.hxx" namespace mitk { void NrrdTbssRoiImageReader ::GenerateData() { try { // Change locale if needed const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'"; setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } // READ IMAGE INFORMATION const unsigned int MINDIM = 3; const unsigned int MAXDIM = 4; MITK_INFO << "loading " << m_FileName << " via mitk::NrrdTbssImageReader... " << std::endl; // Check to see if we can read the file given the name or prefix if ( m_FileName == "" ) { itkWarningMacro( << "Filename is empty!" ) return; } itk::NrrdImageIO::Pointer imageIO = itk::NrrdImageIO::New(); imageIO->SetFileName( m_FileName.c_str() ); imageIO->ReadImageInformation(); unsigned int ndim = imageIO->GetNumberOfDimensions(); if ( ndim < MINDIM || ndim > MAXDIM ) { itkWarningMacro( << "Sorry, only dimensions 3 is supported. The given file has " << ndim << " dimensions!" ) return; } itk::ImageIORegion ioRegion( ndim ); itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize(); itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); unsigned int dimensions[ MAXDIM ]; dimensions[ 0 ] = 0; dimensions[ 1 ] = 0; dimensions[ 2 ] = 0; dimensions[ 3 ] = 0; float spacing[ MAXDIM ]; spacing[ 0 ] = 1.0f; spacing[ 1 ] = 1.0f; spacing[ 2 ] = 1.0f; spacing[ 3 ] = 1.0f; Point3D origin; origin.Fill(0); unsigned int i; for ( i = 0; i < ndim ; ++i ) { ioStart[ i ] = 0; ioSize[ i ] = imageIO->GetDimensions( i ); if(iGetDimensions( i ); spacing[ i ] = imageIO->GetSpacing( i ); if(spacing[ i ] <= 0) spacing[ i ] = 1.0f; } if(i<3) { origin[ i ] = imageIO->GetOrigin( i ); } } ioRegion.SetSize( ioSize ); ioRegion.SetIndex( ioStart ); MITK_INFO << "ioRegion: " << ioRegion << std::endl; imageIO->SetIORegion( ioRegion ); void* buffer = new unsigned char[imageIO->GetImageSizeInBytes()]; imageIO->Read( buffer ); //mitk::Image::Pointer static_cast(this->GetOutput())image = mitk::Image::New(); if((ndim==4) && (dimensions[3]<=1)) ndim = 3; if((ndim==3) && (dimensions[2]<=1)) ndim = 2; mitk::PixelType pixelType( imageIO->GetComponentTypeInfo(), imageIO->GetNumberOfComponents(), imageIO->GetPixelType() ); static_cast(this->GetOutput())->Initialize( pixelType, ndim, dimensions ); static_cast(this->GetOutput())->SetImportChannel( buffer, 0, Image::ManageMemory ); // access direction of itk::Image and include spacing mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (ndim >= 3? 3 : ndim); for ( i=0; i < itkDimMax3; ++i) for( j=0; j < itkDimMax3; ++j ) matrix[i][j] = imageIO->GetDirection(j)[i]; // re-initialize PlaneGeometry with origin and direction PlaneGeometry* planeGeometry = static_cast (static_cast (this->GetOutput())->GetSlicedGeometry(0)->GetGeometry2D(0)); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D* slicedGeometry = static_cast(this->GetOutput())->GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, static_cast(this->GetOutput())->GetDimension(2)); slicedGeometry->SetSpacing(spacing); // re-initialize TimeSlicedGeometry static_cast(this->GetOutput())->GetTimeSlicedGeometry()->InitializeEvenlyTimed(slicedGeometry, static_cast(this->GetOutput())->GetDimension(3)); buffer = NULL; MITK_INFO << "number of image components: "<< static_cast(this->GetOutput())->GetPixelType().GetNumberOfComponents() << std::endl; // READ TBSS HEADER INFORMATION ImageType::Pointer img; std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".roi") { typedef itk::ImageFileReader FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(this->m_FileName); reader->SetImageIO(imageIO); reader->Update(); img = reader->GetOutput(); static_cast(this->GetOutput())->SetImage(img); itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary(); ReadRoiInfo(imgMetaDictionary); } // RESET LOCALE try { MITK_INFO << " ** Changing locale back from " << setlocale(LC_ALL, NULL) << " to '" << currLocale << "'"; setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } MITK_INFO << "...finished!" << std::endl; } catch(std::exception& e) { MITK_INFO << "Std::Exception while reading file!!"; MITK_INFO << e.what(); throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what()); } catch(...) - {http://www.wetter.com/deutschland/heidelberg/DE0004329.html + { MITK_INFO << "Exception while reading file!!"; throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!"); } } void NrrdTbssRoiImageReader ::ReadRoiInfo(itk::MetaDataDictionary dict) { std::vector imgMetaKeys = dict.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; std::vector< itk::Index<3> > roi; for (; itKey != imgMetaKeys.end(); itKey ++) { double x,y,z; itk::Index<3> ix; itk::ExposeMetaData (dict, *itKey, metaString); if (itKey->find("ROI_index") != std::string::npos) { MITK_INFO << *itKey << " ---> " << metaString; sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z); ix[0] = x; ix[1] = y; ix[2] = z; roi.push_back(ix); } else if(itKey->find("preprocessed FA") != std::string::npos) { MITK_INFO << *itKey << " ---> " << metaString; static_cast(this->GetOutput())->SetPreprocessedFA(true); static_cast(this->GetOutput())->SetPreprocessedFAFile(metaString); } // Name of structure if (itKey->find("structure") != std::string::npos) { MITK_INFO << *itKey << " ---> " << metaString; static_cast(this->GetOutput())->SetStructure(metaString); } } static_cast(this->GetOutput())->SetRoi(roi); } const char* NrrdTbssRoiImageReader ::GetFileName() const { return m_FileName.c_str(); } void NrrdTbssRoiImageReader ::SetFileName(const char* aFileName) { m_FileName = aFileName; } const char* NrrdTbssRoiImageReader ::GetFilePrefix() const { return m_FilePrefix.c_str(); } void NrrdTbssRoiImageReader ::SetFilePrefix(const char* aFilePrefix) { m_FilePrefix = aFilePrefix; } const char* NrrdTbssRoiImageReader ::GetFilePattern() const { return m_FilePattern.c_str(); } void NrrdTbssRoiImageReader ::SetFilePattern(const char* aFilePattern) { m_FilePattern = aFilePattern; } bool NrrdTbssRoiImageReader ::CanReadFile(const std::string filename, const std::string filePrefix, const std::string filePattern) { // First check the extension if( filename == "" ) return false; // check if image is serie if( filePattern != "" && filePrefix != "" ) return false; std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".roi") { itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); typedef itk::ImageFileReader FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetImageIO(io); reader->SetFileName(filename); try { reader->Update(); } catch(itk::ExceptionObject e) { MITK_INFO << e.GetDescription(); return false; } return true; } return false; } } //namespace MITK #endif diff --git a/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkTbssImporter.h b/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkTbssImporter.h index 2b02c25b15..3317b07619 100644 --- a/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkTbssImporter.h +++ b/Modules/DiffusionImaging/IODataStructures/TbssImages/mitkTbssImporter.h @@ -1,116 +1,116 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $ Version: $Revision: 18127 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __mitkTbssImporter_h #define __mitkTbssImporter_h #include "mitkCommon.h" #include "mitkFileReader.h" #include "itkImage.h" #include "itkVectorImage.h" #include "itkImageFileReader.h" #include "mitkTbssImage.h" -#include "MitkDiffusionImagingExports.h".h" +#include "MitkDiffusionImagingExports.h" namespace mitk { //template class MitkDiffusionImaging_EXPORT TbssImporter : public itk::Object { public: // typedef TPixelType PixelType; typedef itk::VectorImage DataImageType; // type of the 3d vector image containing the skeletonized images typedef itk::VectorImage VectorImageType; // Datatype of the tbss gradient images typedef itk::Image FloatImage4DType; typedef itk::ImageFileReader FileReaderType4D; typedef itk::ImageFileReader VectorReaderType; typedef itk::Image FloatImage3DType; typedef itk::ImageFileReader FileReaderType3D; mitkClassMacro( TbssImporter, Object ) itkNewMacro(Self) mitk::TbssImage::Pointer Import(); mitk::TbssImage::Pointer ImportMeta(); void SetGroupInfo(std::vector< std::pair > groups) { m_Groups = groups; } std::vector< std::pair > GetGroupInfo() { return m_Groups; } void SetTbssDatasets(std::vector< std::pair > files) { m_MetaFiles = files; } void SetMeasurementInfo(std::string s) { m_MeasurementInfo = s; } std::string GetMeasurementInfo() { return m_MeasurementInfo; } void SetImportVolume(mitk::Image::Pointer inputVolume) { m_InputVolume = inputVolume; } protected: TbssImporter(){} virtual ~TbssImporter(){} DataImageType::Pointer m_Data; std::vector< std::pair > m_Groups; std::vector< std::pair > m_MetaFiles; std::string m_MeasurementInfo; mitk::Image::Pointer m_InputVolume; mitk::TbssImage::MetaDataFunction RetrieveTbssFunction(std::string s); }; } //#include "mitkTbssImporter.cpp" #endif // __mitkTbssImporter_h diff --git a/Modules/DiffusionImaging/Rendering/mitkPlanarPolygonMapper3D.h b/Modules/DiffusionImaging/Rendering/mitkPlanarPolygonMapper3D.h index 73332b32e5..e0d6fa08d0 100644 --- a/Modules/DiffusionImaging/Rendering/mitkPlanarPolygonMapper3D.h +++ b/Modules/DiffusionImaging/Rendering/mitkPlanarPolygonMapper3D.h @@ -1,88 +1,84 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $ Version: $Revision: 17179 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef PlanarPolygonMapper3D_H #define PlanarPolygonMapper3D_H #include #include #include #include #include #include #include #include #include -#include ; - - - - +#include namespace mitk { //##Documentation //## @brief Mapper for FiberBundles //## @ingroup Mapper // template class /*MitkDiffusionImagingMBI_EXPORT*/ PlanarPolygonMapper3D : public VtkMapper3D { public: mitkClassMacro(PlanarPolygonMapper3D, VtkMapper3D); itkNewMacro(Self); const mitk::PlanarPolygon* GetInput(); virtual vtkProp *GetVtkProp(mitk::BaseRenderer *renderer); //looks like depricated.. should be replaced bz GetViewProp() static void SetDefaultProperties(DataNode* node, BaseRenderer* renderer = NULL, bool overwrite = false ); // virtual void ApplyProperties(mitk::BaseRenderer* renderer); static void SetVtkMapperImmediateModeRendering(vtkMapper *mapper); virtual void GenerateDataForRenderer(mitk::BaseRenderer* renderer); virtual void GenerateData(); protected: PlanarPolygonMapper3D(); virtual ~PlanarPolygonMapper3D(); void UpdateVtkObjects(); vtkPoints* m_points; vtkPolygon* m_polygon; vtkPolyData* m_polygonPolyData; vtkCellArray* m_polygonsCell; vtkOpenGLPolyDataMapper *m_VtkPolygonDataMapperGL; vtkOpenGLActor *m_PolygonActor; vtkPropAssembly *m_PolygonAssembly; }; } // namespace mitk #endif /* FiberBundleMapper3D_H_HEADER_INCLUDED */ diff --git a/Modules/MitkExt/Algorithms/mitkMaskImageFilter.cpp b/Modules/MitkExt/Algorithms/mitkMaskImageFilter.cpp index aea97685b9..66d5d1350a 100644 --- a/Modules/MitkExt/Algorithms/mitkMaskImageFilter.cpp +++ b/Modules/MitkExt/Algorithms/mitkMaskImageFilter.cpp @@ -1,185 +1,186 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkMaskImageFilter.h" #include "mitkImageTimeSelector.h" #include "mitkTimeHelper.h" #include "mitkProperties.h" #include "mitkImageToItk.h" #include "mitkImageAccessByItk.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionIteratorWithIndex.h" +#include + mitk::MaskImageFilter::MaskImageFilter() : m_Mask(NULL) { this->SetNumberOfInputs(2); this->SetNumberOfRequiredInputs(2); m_InputTimeSelector = mitk::ImageTimeSelector::New(); m_MaskTimeSelector = mitk::ImageTimeSelector::New(); m_OutputTimeSelector = mitk::ImageTimeSelector::New(); m_OverrideOutsideValue = false; m_OutsideValue = 0; } mitk::MaskImageFilter::~MaskImageFilter() { } void mitk::MaskImageFilter::SetMask( const mitk::Image* mask ) { // Process object is not const-correct so the const_cast is required here m_Mask = const_cast< mitk::Image * >( mask ); this->ProcessObject::SetNthInput(1, m_Mask ); } const mitk::Image* mitk::MaskImageFilter::GetMask() const { return m_Mask; } void mitk::MaskImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); mitk::Image* output = this->GetOutput(); mitk::Image* input = const_cast< mitk::Image * > ( this->GetInput() ); mitk::Image* mask = m_Mask ; if((output->IsInitialized()==false) || (mask == NULL) || (mask->GetTimeSlicedGeometry()->GetTimeSteps() == 0)) return; input->SetRequestedRegionToLargestPossibleRegion(); mask->SetRequestedRegionToLargestPossibleRegion(); GenerateTimeInInputRegion(output, input); GenerateTimeInInputRegion(output, mask); } void mitk::MaskImageFilter::GenerateOutputInformation() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) return; itkDebugMacro(<<"GenerateOutputInformation()"); output->Initialize(input->GetPixelType(), *input->GetTimeSlicedGeometry()); output->SetPropertyList(input->GetPropertyList()->Clone()); m_TimeOfHeaderInitialization.Modified(); } template < typename TPixel, unsigned int VImageDimension > void mitk::MaskImageFilter::InternalComputeMask(itk::Image* inputItkImage) { typedef itk::Image ItkInputImageType; typedef itk::Image ItkMaskImageType; typedef itk::Image ItkOutputImageType; typedef itk::ImageRegionConstIterator< ItkInputImageType > ItkInputImageIteratorType; typedef itk::ImageRegionConstIterator< ItkMaskImageType > ItkMaskImageIteratorType; typedef itk::ImageRegionIteratorWithIndex< ItkOutputImageType > ItkOutputImageIteratorType; typename mitk::ImageToItk::Pointer maskimagetoitk = mitk::ImageToItk::New(); maskimagetoitk->SetInput(m_MaskTimeSelector->GetOutput()); maskimagetoitk->Update(); typename ItkMaskImageType::Pointer maskItkImage = maskimagetoitk->GetOutput(); typename mitk::ImageToItk::Pointer outputimagetoitk = mitk::ImageToItk::New(); outputimagetoitk->SetInput(m_OutputTimeSelector->GetOutput()); outputimagetoitk->Update(); typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput(); // create the iterators typename ItkInputImageType::RegionType inputRegionOfInterest = inputItkImage->GetLargestPossibleRegion(); ItkInputImageIteratorType inputIt( inputItkImage, inputRegionOfInterest ); ItkMaskImageIteratorType maskIt ( maskItkImage, inputRegionOfInterest ); ItkOutputImageIteratorType outputIt( outputItkImage, inputRegionOfInterest ); //typename ItkOutputImageType::PixelType outsideValue = itk::NumericTraits::min(); if ( !m_OverrideOutsideValue ) m_OutsideValue = itk::NumericTraits::min(); - m_MinValue = (float)(itk::NumericTraits::max()); - m_MaxValue = (float)(itk::NumericTraits::min()); - + m_MinValue = std::numeric_limits::max(); + m_MaxValue = std::numeric_limits::min(); for ( inputIt.GoToBegin(), maskIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd() && !maskIt.IsAtEnd(); ++inputIt, ++maskIt, ++outputIt) { if ( maskIt.Get() > itk::NumericTraits::Zero ) { outputIt.Set(inputIt.Get()); m_MinValue = vnl_math_min((float)inputIt.Get(), (float)m_MinValue); m_MaxValue = vnl_math_max((float)inputIt.Get(), (float)m_MaxValue); } else { outputIt.Set(m_OutsideValue); } } } void mitk::MaskImageFilter::GenerateData() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer mask = m_Mask; mitk::Image::Pointer output = this->GetOutput(); if((output->IsInitialized()==false) || (mask.IsNull()) || (mask->GetTimeSlicedGeometry()->GetTimeSteps() == 0)) return; m_InputTimeSelector->SetInput(input); m_MaskTimeSelector->SetInput(mask); m_OutputTimeSelector->SetInput(this->GetOutput()); mitk::Image::RegionType outputRegion = output->GetRequestedRegion(); const mitk::TimeSlicedGeometry *outputTimeGeometry = output->GetTimeSlicedGeometry(); const mitk::TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry(); const mitk::TimeSlicedGeometry *maskTimeGeometry = mask->GetTimeSlicedGeometry(); ScalarType timeInMS; int timestep=0; int tstart=outputRegion.GetIndex(3); int tmax=tstart+outputRegion.GetSize(3); int t; for(t=tstart;tTimeStepToMS( t ); timestep = inputTimeGeometry->MSToTimeStep( timeInMS ); m_InputTimeSelector->SetTimeNr(timestep); m_InputTimeSelector->UpdateLargestPossibleRegion(); m_OutputTimeSelector->SetTimeNr(t); m_OutputTimeSelector->UpdateLargestPossibleRegion(); timestep = maskTimeGeometry->MSToTimeStep( timeInMS ); m_MaskTimeSelector->SetTimeNr(timestep); m_MaskTimeSelector->UpdateLargestPossibleRegion(); AccessByItk(m_InputTimeSelector->GetOutput(),InternalComputeMask); } m_TimeOfHeaderInitialization.Modified(); } diff --git a/Modules/MitkExt/DataManagement/mitkOrganTypeProperty.h b/Modules/MitkExt/DataManagement/mitkOrganTypeProperty.h index 19ab92f1c7..733367ed46 100644 --- a/Modules/MitkExt/DataManagement/mitkOrganTypeProperty.h +++ b/Modules/MitkExt/DataManagement/mitkOrganTypeProperty.h @@ -1,68 +1,77 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef mitkOrganTypeProperty_h_Included #define mitkOrganTypeProperty_h_Included #include "mitkCommon.h" #include "MitkExtExports.h" #include "mitkEnumerationProperty.h" #include namespace mitk { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4522) +#endif + /** \brief Enumerates all known organs :-) \sa QmitkInteractiveSegmentation \ingroup ToolManagerEtAl \ingroup DataManagement Last contributor $Author$ */ class MitkExt_EXPORT OrganTypeProperty : public EnumerationProperty { public: mitkClassMacro(OrganTypeProperty, EnumerationProperty); itkNewMacro(OrganTypeProperty); mitkNewMacro1Param(OrganTypeProperty, const IdType&); mitkNewMacro1Param(OrganTypeProperty, const std::string&); using BaseProperty::operator=; protected: OrganTypeProperty(); OrganTypeProperty( const IdType& value ); OrganTypeProperty( const std::string& value ); virtual ~OrganTypeProperty(); virtual void AddEnumerationTypes(); private: // purposely not implemented OrganTypeProperty(const OrganTypeProperty&); OrganTypeProperty& operator=(const OrganTypeProperty&); }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } // namespace #endif diff --git a/Modules/MitkExt/DataManagement/mitkPropertyObserver.h b/Modules/MitkExt/DataManagement/mitkPropertyObserver.h index 9734a61f22..11e2192c1f 100644 --- a/Modules/MitkExt/DataManagement/mitkPropertyObserver.h +++ b/Modules/MitkExt/DataManagement/mitkPropertyObserver.h @@ -1,97 +1,95 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITK_BASEPROPERTYOBSERVER_H_INCLUDED #define MITK_BASEPROPERTYOBSERVER_H_INCLUDED -#pragma GCC visibility push(default) #include -#pragma GCC visibility pop #include "MitkExtExports.h" #include "mitkCommon.h" namespace mitk { /** \brief Convenience class to observe changes of a mitk::BaseProperty. This class registers itself as an ITK observer to a BaseProperty and gets informed of changes to the property. Whenever such a change occurrs, the virtual method PropertyChanged() or PropertyRemoved() is called. This way, derived classes can implement behaviour for more specific properties (e.g. ColorProperty) without the need to reimplement the Subject-Observer handling. */ class BaseProperty; class MitkExt_EXPORT PropertyObserver { public: PropertyObserver(); virtual ~PropertyObserver(); virtual void PropertyChanged() = 0; virtual void PropertyRemoved() = 0; protected: void BeginModifyProperty(); void EndModifyProperty(); unsigned long m_ModifiedTag; unsigned long m_DeleteTag; bool m_SelfCall; }; class MitkExt_EXPORT PropertyView : public PropertyObserver { public: PropertyView( const mitk::BaseProperty* ); virtual ~PropertyView(); void OnModified(const itk::EventObject& e); void OnDelete(const itk::EventObject& e); protected: const mitk::BaseProperty* m_Property; }; class MitkExt_EXPORT PropertyEditor : public PropertyObserver { public: PropertyEditor( mitk::BaseProperty* ); virtual ~PropertyEditor(); void OnModified(const itk::EventObject& e); void OnDelete(const itk::EventObject& e); protected: mitk::BaseProperty* m_Property; }; } #endif diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index ca9f07f611..87cccef92c 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -1,37 +1,36 @@ -SUPPRESS_VC8_DEPRECATED_WARNINGS() SUPPRESS_ALL_WARNINGS() # most stuff of these uses itk_zlib.h (via mitkIpPic.h) FIND_PACKAGE(ITK) INCLUDE(${ITK_USE_FILE}) # some legacy util files include in the old style with prefixed directory, # like #include INCLUDE_DIRECTORIES(.) SUBDIRS(ann ipSegmentation IIL4MITK pic2vtk tinyxml Poco qwt qxt mbilog glew vecmath) # mbilog is independent of mitk, and cant use mitk macros # configuring happens through mbilog/mbilogConfig.cmake.in SET(mbilog_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/mbilog" "${CMAKE_CURRENT_BINARY_DIR}/mbilog") SET(mbilog_CONFIG_FILE "${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/mbilogConfig.cmake" CACHE INTERNAL "Path to module config" FORCE) CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/mbilog/mbilogConfig.cmake.in" "${mbilog_CONFIG_FILE}") # IF(NOT MITK_CHILI_PLUGIN) SUBDIRS(ipPic ipFunc) ADD_SUBDIRECTORY(KWStyle) # ENDIF(NOT MITK_CHILI_PLUGIN) SET(Poco_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Poco CACHE PATH "top-level directory containing the poco include directories. E.g /usr/local/include/ or c:\\poco\\include\\poco-1.3.2" ) SET(Poco_LIBRARY_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} CACHE PATH "top-level directory containing the poco libraries." )