diff --git a/CMake/mitkFunctionCreateModule.cmake b/CMake/mitkFunctionCreateModule.cmake index 2e4f46b639..3aeba861c4 100644 --- a/CMake/mitkFunctionCreateModule.cmake +++ b/CMake/mitkFunctionCreateModule.cmake @@ -1,654 +1,656 @@ ################################################################## # # mitk_create_module # #! Creates a module for the automatic module dependency system within MITK. #! #! Example: #! #! \code #! mitk_create_module( #! DEPENDS PUBLIC MitkCore #! PACKAGE_DEPENDS #! PRIVATE Qt5|Xml+Networking #! PUBLIC ITK|Watershed #! \endcode #! #! The parameter specifies the name of the module which is used #! to create a logical target name. The parameter is optional in case the #! MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME variable evaluates to TRUE. The #! module name will then be derived from the directory name in which this #! function is called. #! #! If set, the following variables will be used to validate the module name: #! #! MITK_MODULE_NAME_REGEX_MATCH The module name must match this regular expression. #! MITK_MODULE_NAME_REGEX_NOT_MATCH The module name must not match this regular expression. #! #! If the MITK_MODULE_NAME_PREFIX variable is set, the module name will be prefixed #! with its contents. #! #! A modules source files are specified in a separate CMake file usually #! called files.cmake, located in the module root directory. The #! mitk_create_module() macro evaluates the following CMake variables #! from the files.cmake file: #! #! - CPP_FILES A list of .cpp files #! - H_FILES A list of .h files without a corresponding .cpp file #! - TXX_FILES A list of .txx files #! - RESOURCE_FILES A list of files (resources) which are embedded into the module #! - MOC_H_FILES A list of Qt header files which should be processed by the MOC #! - UI_FILES A list of .ui Qt UI files #! - QRC_FILES A list of .qrc Qt resource files #! - DOX_FILES A list of .dox Doxygen files #! #! List of variables available after the function is called: #! - MODULE_NAME #! - MODULE_TARGET #! - MODULE_IS_ENABLED #! - MODULE_SUBPROJECTS #! #! \sa mitk_create_executable #! #! Parameters (all optional): #! #! \param The module name (also used as target name) #! \param FILES_CMAKE File name of a CMake file setting source list variables #! (defaults to files.cmake) #! \param VERSION Module version number, e.g. "1.2.0" #! \param AUTOLOAD_WITH A module target name identifying the module which will #! trigger the automatic loading of this module #! \param DEPRECATED_SINCE Marks this modules as deprecated since #! \param DESCRIPTION A description for this module #! #! Multi-value Parameters (all optional): #! #! \param SUBPROJECTS List of CDash labels #! \param INCLUDE_DIRS Include directories for this module: #! \verbatim #! [[PUBLIC|PRIVATE|INTERFACE] ...]... #! \endverbatim #! The default scope for include directories is PUBLIC. #! \param DEPENDS List of module dependencies: #! \verbatim #! [[PUBLIC|PRIVATE|INTERFACE] ...]... #! \endverbatim #! The default scope for module dependencies is PUBLIC. #! \param PACKAGE_DEPENDS List of public packages dependencies (e.g. Qt, VTK, etc.). #! Package dependencies have the following syntax: #! \verbatim #! [PUBLIC|PRIVATE|INTERFACE] PACKAGE[|COMPONENT1[+COMPONENT2]...] #! \endverbatim #! The default scope for package dependencies is PRIVATE. #! \param ADDITIONAL_LIBS List of additional private libraries linked to this module. #! The folder containing the library will be added to the global list of library search paths. #! \param CPP_FILES List of source files for this module. If the list is non-empty, #! the module does not need to provide a files.cmake file or FILES_CMAKE argument. #! \param H_FILES List of public header files for this module. It is recommended to use #! a files.cmake file instead. #! #! Options (optional) #! #! \param FORCE_STATIC Force building this module as a static library #! \param GCC_DEFAULT_VISIBILITY Do not use gcc visibility flags - all #! symbols will be exported #! \param NO_INIT Do not create CppMicroServices initialization code #! \param NO_FEATURE_INFO Do not create a feature info by calling add_feature_info() #! \param WARNINGS_NO_ERRORS Do not treat compiler warnings as errors # ################################################################## function(mitk_create_module) set(_macro_params VERSION # module version number, e.g. "1.2.0" EXPORT_DEFINE # export macro name for public symbols of this module (DEPRECATED) AUTOLOAD_WITH # a module target name identifying the module which will trigger the # automatic loading of this module FILES_CMAKE # file name of a CMake file setting source list variables # (defaults to files.cmake) DEPRECATED_SINCE # marks this modules as deprecated DESCRIPTION # a description for this module ) set(_macro_multiparams SUBPROJECTS # list of CDash labels INCLUDE_DIRS # include directories: [PUBLIC|PRIVATE|INTERFACE] INTERNAL_INCLUDE_DIRS # include dirs internal to this module (DEPRECATED) DEPENDS # list of modules this module depends on: [PUBLIC|PRIVATE|INTERFACE] DEPENDS_INTERNAL # list of modules this module internally depends on (DEPRECATED) PACKAGE_DEPENDS # list of "packages this module depends on (e.g. Qt, VTK, etc.): [PUBLIC|PRIVATE|INTERFACE] TARGET_DEPENDS # list of CMake targets this module should depend on ADDITIONAL_LIBS # list of addidtional private libraries linked to this module. CPP_FILES # list of cpp files H_FILES # list of header files: [PUBLIC|PRIVATE] ) set(_macro_options FORCE_STATIC # force building this module as a static library HEADERS_ONLY # this module is a headers-only library GCC_DEFAULT_VISIBILITY # do not use gcc visibility flags - all symbols will be exported NO_DEFAULT_INCLUDE_DIRS # do not add default include directories like "include" or "." NO_INIT # do not create CppMicroServices initialization code NO_FEATURE_INFO # do not create a feature info by calling add_feature_info() WARNINGS_NO_ERRORS # do not treat compiler warnings as errors EXECUTABLE # create an executable; do not use directly, use mitk_create_executable() instead C_MODULE # compile all source files as C sources CXX_MODULE # compile all source files as C++ sources ) cmake_parse_arguments(MODULE "${_macro_options}" "${_macro_params}" "${_macro_multiparams}" ${ARGN}) set(MODULE_NAME ${MODULE_UNPARSED_ARGUMENTS}) # ----------------------------------------------------------------- # Sanity checks if(NOT MODULE_NAME) if(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME) get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) else() message(SEND_ERROR "The module name must not be empty") endif() endif() set(_deprecated_args INTERNAL_INCLUDE_DIRS DEPENDS_INTERNAL EXPORT_DEFINE TARGET_DEPENDS HEADERS_ONLY) foreach(_deprecated_arg ${_deprecated_args}) if(MODULE_${_deprecated_arg}) message(WARNING "The ${_deprecated_arg} argument is deprecated") endif() endforeach() set(_module_type module) set(_Module_type Module) if(MODULE_EXECUTABLE) set(_module_type executable) set(_Module_type Executable) endif() if(MITK_MODULE_NAME_REGEX_MATCH) if(NOT ${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_MATCH}) message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" does not match the regular expression \"${MITK_MODULE_NAME_REGEX_MATCH}\".") endif() endif() if(MITK_MODULE_NAME_REGEX_NOT_MATCH) if(${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_NOT_MATCH}) message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" must not match the regular expression \"${MITK_MODULE_NAME_REGEX_NOT_MATCH}\".") endif() endif() if(MITK_MODULE_NAME_PREFIX AND NOT MODULE_NAME MATCHES "^${MITK_MODULE_NAME_PREFIX}.*$") set(MODULE_NAME "${MITK_MODULE_NAME_PREFIX}${MODULE_NAME}") endif() if(NOT MODULE_FILES_CMAKE) set(MODULE_FILES_CMAKE files.cmake) endif() if(NOT IS_ABSOLUTE ${MODULE_FILES_CMAKE}) set(MODULE_FILES_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FILES_CMAKE}) endif() if(NOT MODULE_SUBPROJECTS) if(MITK_DEFAULT_SUBPROJECTS) set(MODULE_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS}) + else() + set(MODULE_SUBPROJECTS MITK-Modules) endif() endif() # check if the subprojects exist as targets if(MODULE_SUBPROJECTS) foreach(subproject ${MODULE_SUBPROJECTS}) if(NOT TARGET ${subproject}) message(SEND_ERROR "The subproject ${subproject} does not have a corresponding target") endif() endforeach() endif() # ----------------------------------------------------------------- # Check if module should be build set(MODULE_TARGET ${MODULE_NAME}) # assume worst case set(MODULE_IS_ENABLED 0) # first we check if we have an explicit module build list if(MITK_MODULES_TO_BUILD) list(FIND MITK_MODULES_TO_BUILD ${MODULE_NAME} _MOD_INDEX) if(_MOD_INDEX EQUAL -1) set(MODULE_IS_EXCLUDED 1) endif() endif() if(NOT MODULE_IS_EXCLUDED) # first of all we check for the dependencies _mitk_parse_package_args(${MODULE_PACKAGE_DEPENDS}) mitk_check_module_dependencies(MODULES ${MODULE_DEPENDS} PACKAGES ${PACKAGE_NAMES} MISSING_DEPENDENCIES_VAR _MISSING_DEP PACKAGE_DEPENDENCIES_VAR PACKAGE_NAMES) if(_MISSING_DEP) if(MODULE_NO_FEATURE_INFO) message("${_Module_type} ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}") endif() set(MODULE_IS_ENABLED 0) else() set(MODULE_IS_ENABLED 1) # now check for every package if it is enabled. This overlaps a bit with # MITK_CHECK_MODULE ... foreach(_package ${PACKAGE_NAMES}) if((DEFINED MITK_USE_${_package}) AND NOT (MITK_USE_${_package})) message("${_Module_type} ${MODULE_NAME} won't be built. Turn on MITK_USE_${_package} if you want to use it.") set(MODULE_IS_ENABLED 0) break() endif() endforeach() endif() endif() # ----------------------------------------------------------------- # Start creating the module if(MODULE_IS_ENABLED) # clear variables defined in files.cmake set(RESOURCE_FILES ) set(CPP_FILES ) set(H_FILES ) set(TXX_FILES ) set(DOX_FILES ) set(UI_FILES ) set(MOC_H_FILES ) set(QRC_FILES ) # clear other variables set(Q${KITNAME}_GENERATED_CPP ) set(Q${KITNAME}_GENERATED_MOC_CPP ) set(Q${KITNAME}_GENERATED_QRC_CPP ) set(Q${KITNAME}_GENERATED_UI_CPP ) # check and set-up auto-loading if(MODULE_AUTOLOAD_WITH) if(NOT TARGET "${MODULE_AUTOLOAD_WITH}") message(SEND_ERROR "The module target \"${MODULE_AUTOLOAD_WITH}\" specified as the auto-loading module for \"${MODULE_NAME}\" does not exist") endif() endif() set(_module_autoload_meta_target "${CMAKE_PROJECT_NAME}-autoload") # create a meta-target if it does not already exist if(NOT TARGET ${_module_autoload_meta_target}) add_custom_target(${_module_autoload_meta_target}) endif() if(NOT MODULE_EXPORT_DEFINE) set(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT) endif() if(MITK_GENERATE_MODULE_DOT) message("MODULEDOTNAME ${MODULE_NAME}") foreach(dep ${MODULE_DEPENDS}) message("MODULEDOT \"${MODULE_NAME}\" -> \"${dep}\" ; ") endforeach(dep) endif(MITK_GENERATE_MODULE_DOT) if (EXISTS ${MODULE_FILES_CMAKE}) include(${MODULE_FILES_CMAKE}) endif() if(MODULE_CPP_FILES) list(APPEND CPP_FILES ${MODULE_CPP_FILES}) endif() if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src") # Preprend the "src" directory to the cpp file list set(_cpp_files ${CPP_FILES}) set(CPP_FILES ) foreach(_cpp_file ${_cpp_files}) list(APPEND CPP_FILES "src/${_cpp_file}") endforeach() endif() if(CPP_FILES OR RESOURCE_FILES OR UI_FILES OR MOC_H_FILES OR QRC_FILES) set(MODULE_HEADERS_ONLY 0) if(MODULE_C_MODULE) set_source_files_properties(${CPP_FILES} PROPERTIES LANGUAGE C) elseif(MODULE_CXX_MODULE) set_source_files_properties(${CPP_FILES} PROPERTIES LANGUAGE CXX) endif() else() set(MODULE_HEADERS_ONLY 1) if(MODULE_AUTOLOAD_WITH) message(SEND_ERROR "A headers only module cannot be auto-loaded") endif() endif() set(module_c_flags ) set(module_c_flags_debug ) set(module_c_flags_release ) set(module_cxx_flags ) set(module_cxx_flags_debug ) set(module_cxx_flags_release ) if(MODULE_GCC_DEFAULT_VISIBILITY OR NOT CMAKE_COMPILER_IS_GNUCXX) # We only support hidden visibility for gcc for now. Clang still has troubles with # correctly marking template declarations and explicit template instantiations as exported. # See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028 # and http://llvm.org/bugs/show_bug.cgi?id=10113 set(CMAKE_CXX_VISIBILITY_PRESET default) set(CMAKE_VISIBILITY_INLINES_HIDDEN 0) else() set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) endif() if(NOT MODULE_WARNINGS_NO_ERRORS) if(MSVC_VERSION) mitkFunctionCheckCAndCXXCompilerFlags("/WX" module_c_flags module_cxx_flags) else() mitkFunctionCheckCAndCXXCompilerFlags(-Werror module_c_flags module_cxx_flags) # The flag "c++0x-static-nonintegral-init" has been renamed in newer Clang # versions to "static-member-init", see # http://clang-developers.42468.n3.nabble.com/Wc-0x-static-nonintegral-init-gone-td3999651.html # # Also, older Clang and seemingly all gcc versions do not warn if unknown # "-no-*" flags are used, so CMake will happily append any -Wno-* flag to the # command line. This may get confusing if unrelated compiler errors happen and # the error output then additionally contains errors about unknown flags (which # is not the case if there were no compile errors). # # So instead of using -Wno-* we use -Wno-error=*, which will be properly rejected by # the compiler and if applicable, prints the specific warning as a real warning and # not as an error (although -Werror was given). mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=static-member-init" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unknown-warning" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=gnu" module_c_flags module_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=inconsistent-missing-override" module_c_flags module_cxx_flags) endif() endif() if(MODULE_FORCE_STATIC) set(_STATIC STATIC) else() set(_STATIC ) endif(MODULE_FORCE_STATIC) if(NOT MODULE_HEADERS_ONLY) if(NOT MODULE_NO_INIT OR RESOURCE_FILES) find_package(CppMicroServices QUIET NO_MODULE REQUIRED) endif() if(NOT MODULE_NO_INIT) usFunctionGenerateModuleInit(CPP_FILES) endif() set(binary_res_files ) set(source_res_files ) if(RESOURCE_FILES) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/resource") set(res_dir resource) elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Resources") set(res_dir Resources) else() message(SEND_ERROR "Resources specified but ${CMAKE_CURRENT_SOURCE_DIR}/resource directory not found.") endif() foreach(res_file ${RESOURCE_FILES}) if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}/${res_file}) list(APPEND binary_res_files "${res_file}") else() list(APPEND source_res_files "${res_file}") endif() endforeach() # Add a source level dependencies on resource files usFunctionGetResourceSource(TARGET ${MODULE_TARGET} OUT CPP_FILES) endif() endif() if(MITK_USE_Qt5) if(UI_FILES) qt5_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES}) endif() if(MOC_H_FILES) qt5_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) endif() if(QRC_FILES) qt5_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES}) endif() endif() set(Q${KITNAME}_GENERATED_CPP ${Q${KITNAME}_GENERATED_CPP} ${Q${KITNAME}_GENERATED_UI_CPP} ${Q${KITNAME}_GENERATED_MOC_CPP} ${Q${KITNAME}_GENERATED_QRC_CPP}) mitkFunctionOrganizeSources( SOURCE ${CPP_FILES} HEADER ${H_FILES} TXX ${TXX_FILES} DOC ${DOX_FILES} UI ${UI_FILES} QRC ${QRC_FILES} MOC ${Q${KITNAME}_GENERATED_MOC_CPP} GEN_QRC ${Q${KITNAME}_GENERATED_QRC_CPP} GEN_UI ${Q${KITNAME}_GENERATED_UI_CPP} ) set(coverage_sources ${CPP_FILES} ${H_FILES} ${GLOBBED__H_FILES} ${CORRESPONDING__H_FILES} ${TXX_FILES} ${TOOL_CPPS} ${TOOL_GUI_CPPS}) if(MODULE_SUBPROJECTS) set_property(SOURCE ${coverage_sources} APPEND PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK) endif() # --------------------------------------------------------------- # Create the actual module target if(MODULE_HEADERS_ONLY) add_library(${MODULE_TARGET} INTERFACE) else() if(MODULE_EXECUTABLE) add_executable(${MODULE_TARGET} ${MODULE_CPP_FILES} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP} ${DOX_FILES} ${UI_FILES} ${QRC_FILES}) set(_us_module_name main) else() add_library(${MODULE_TARGET} ${_STATIC} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP} ${DOX_FILES} ${UI_FILES} ${QRC_FILES}) set(_us_module_name ${MODULE_TARGET}) endif() # Apply properties to the module target. target_compile_definitions(${MODULE_TARGET} PRIVATE US_MODULE_NAME=${_us_module_name}) if(MODULE_C_MODULE) if(module_c_flags) string(REPLACE " " ";" module_c_flags "${module_c_flags}") target_compile_options(${MODULE_TARGET} PRIVATE ${module_c_flags}) endif() if(module_c_flags_debug) string(REPLACE " " ";" module_c_flags_debug "${module_c_flags_debug}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_c_flags_debug}>) endif() if(module_c_flags_release) string(REPLACE " " ";" module_c_flags_release "${module_c_flags_release}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_c_flags_release}>) endif() else() if(module_cxx_flags) string(REPLACE " " ";" module_cxx_flags "${module_cxx_flags}") target_compile_options(${MODULE_TARGET} PRIVATE ${module_cxx_flags}) endif() if(module_cxx_flags_debug) string(REPLACE " " ";" module_cxx_flags_debug "${module_cxx_flags_debug}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_cxx_flags_debug}>) endif() if(module_cxx_flags_release) string(REPLACE " " ";" module_cxx_flags_release "${module_cxx_flags_release}") target_compile_options(${MODULE_TARGET} PRIVATE $<$:${module_cxx_flags_release}>) endif() endif() set_property(TARGET ${MODULE_TARGET} PROPERTY US_MODULE_NAME ${_us_module_name}) if(MINGW) target_link_libraries(${MODULE_TARGET} ssp) # add stack smash protection lib endif() # Add additional library search directories to a global property which # can be evaluated by other CMake macros, e.g. our install scripts. if(MODULE_ADDITIONAL_LIBS) target_link_libraries(${MODULE_TARGET} PRIVATE ${MODULE_ADDITIONAL_LIBS}) get_property(_mitk_additional_library_search_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) foreach(_lib_filepath ${MODULE_ADDITIONAL_LIBS}) get_filename_component(_search_path "${_lib_filepath}" PATH) if(_search_path) list(APPEND _mitk_additional_library_search_paths "${_search_path}") endif() endforeach() if(_mitk_additional_library_search_paths) list(REMOVE_DUPLICATES _mitk_additional_library_search_paths) set_property(GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS ${_mitk_additional_library_search_paths}) endif() endif() # add the target name to a global property which is used in the top-level # CMakeLists.txt file to export the target set_property(GLOBAL APPEND PROPERTY MITK_MODULE_TARGETS ${MODULE_TARGET}) if(MODULE_AUTOLOAD_WITH) # for auto-loaded modules, adapt the output directory add_dependencies(${_module_autoload_meta_target} ${MODULE_TARGET}) if(WIN32) set(_module_output_prop RUNTIME_OUTPUT_DIRECTORY) else() set(_module_output_prop LIBRARY_OUTPUT_DIRECTORY) endif() set(_module_output_dir ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH}) get_target_property(_module_is_imported ${MODULE_AUTOLOAD_WITH} IMPORTED) if(NOT _module_is_imported) # if the auto-loading module is not imported, get its location # and put the auto-load module relative to it. get_target_property(_module_output_dir ${MODULE_AUTOLOAD_WITH} ${_module_output_prop}) set_target_properties(${MODULE_TARGET} PROPERTIES ${_module_output_prop} ${_module_output_dir}/${MODULE_AUTOLOAD_WITH}) else() set_target_properties(${MODULE_TARGET} PROPERTIES ${_module_output_prop} ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH}) endif() set_target_properties(${MODULE_TARGET} PROPERTIES MITK_AUTOLOAD_DIRECTORY ${MODULE_AUTOLOAD_WITH}) # add the auto-load module name as a property set_property(TARGET ${MODULE_AUTOLOAD_WITH} APPEND PROPERTY MITK_AUTOLOAD_TARGETS ${MODULE_TARGET}) endif() if(binary_res_files) usFunctionAddResources(TARGET ${MODULE_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${res_dir} FILES ${binary_res_files}) endif() if(source_res_files) usFunctionAddResources(TARGET ${MODULE_TARGET} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${res_dir} FILES ${source_res_files}) endif() if(binary_res_files OR source_res_files) usFunctionEmbedResources(TARGET ${MODULE_TARGET}) endif() if(MODULE_DEPRECATED_SINCE) set_property(TARGET ${MODULE_TARGET} PROPERTY MITK_MODULE_DEPRECATED_SINCE ${MODULE_DEPRECATED_SINCE}) endif() # create export macros if (NOT MODULE_EXECUTABLE) set(_export_macro_name ) if(MITK_LEGACY_EXPORT_MACRO_NAME) set(_export_macro_names EXPORT_MACRO_NAME ${MODULE_EXPORT_DEFINE} NO_EXPORT_MACRO_NAME ${MODULE_NAME}_NO_EXPORT DEPRECATED_MACRO_NAME ${MODULE_NAME}_DEPRECATED NO_DEPRECATED_MACRO_NAME ${MODULE_NAME}_NO_DEPRECATED ) endif() generate_export_header(${MODULE_NAME} ${_export_macro_names} EXPORT_FILE_NAME ${MODULE_NAME}Exports.h ) endif() target_include_directories(${MODULE_TARGET} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) endif() # --------------------------------------------------------------- # Properties for both header-only and compiled modules if(MODULE_HEADERS_ONLY) set(_module_property_type INTERFACE) else() set(_module_property_type PUBLIC) endif() if(MODULE_TARGET_DEPENDS) add_dependencies(${MODULE_TARGET} ${MODULE_TARGET_DEPENDS}) endif() if(MODULE_SUBPROJECTS AND NOT MODULE_HEADERS_ONLY) set_property(TARGET ${MODULE_TARGET} PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK) foreach(subproject ${MODULE_SUBPROJECTS}) add_dependencies(${subproject} ${MODULE_TARGET}) endforeach() endif() set(DEPENDS "${MODULE_DEPENDS}") if(NOT MODULE_NO_INIT AND NOT MODULE_HEADERS_ONLY) # Add a CppMicroServices dependency implicitly, since it is # needed for the generated "module initialization" code. set(DEPENDS "CppMicroServices;${DEPENDS}") endif() if(DEPENDS OR MODULE_PACKAGE_DEPENDS) mitk_use_modules(TARGET ${MODULE_TARGET} MODULES ${DEPENDS} PACKAGES ${MODULE_PACKAGE_DEPENDS} ) endif() if(NOT MODULE_C_MODULE) target_compile_features(${MODULE_TARGET} ${_module_property_type} ${MITK_CXX_FEATURES}) endif() # add include directories if(MODULE_INTERNAL_INCLUDE_DIRS) target_include_directories(${MODULE_TARGET} PRIVATE ${MODULE_INTERNAL_INCLUDE_DIRS}) endif() if(NOT MODULE_NO_DEFAULT_INCLUDE_DIRS) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(${MODULE_TARGET} ${_module_property_type} include) else() target_include_directories(${MODULE_TARGET} ${_module_property_type} .) endif() if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/src) target_include_directories(${MODULE_TARGET} PRIVATE src) endif() endif() target_include_directories(${MODULE_TARGET} ${_module_property_type} ${MODULE_INCLUDE_DIRS}) endif() # ----------------------------------------------------------------- # Record missing dependency information if(_MISSING_DEP) if(MODULE_DESCRIPTION) set(MODULE_DESCRIPTION "${MODULE_DESCRIPTION} (missing dependencies: ${_MISSING_DEP})") else() set(MODULE_DESCRIPTION "(missing dependencies: ${_MISSING_DEP})") endif() endif() if(NOT MODULE_NO_FEATURE_INFO) add_feature_info(${MODULE_NAME} MODULE_IS_ENABLED "${MODULE_DESCRIPTION}") endif() set(MODULE_NAME ${MODULE_NAME} PARENT_SCOPE) set(MODULE_TARGET ${MODULE_TARGET} PARENT_SCOPE) set(MODULE_IS_ENABLED ${MODULE_IS_ENABLED} PARENT_SCOPE) set(MODULE_SUBPROJECTS ${MODULE_SUBPROJECTS} PARENT_SCOPE) endfunction() diff --git a/CMake/mitkFunctionCreatePlugin.cmake b/CMake/mitkFunctionCreatePlugin.cmake index 276e014c06..0cd1499508 100644 --- a/CMake/mitkFunctionCreatePlugin.cmake +++ b/CMake/mitkFunctionCreatePlugin.cmake @@ -1,339 +1,343 @@ #! \brief Creates a MITK CTK plugin. #! #! This function should be called from the plugins CMakeLists.txt file. #! The target name is available after the macro call as ${PLUGIN_TARGET} #! to add additional libraries in your CMakeLists.txt. Include paths and link #! libraries are set depending on the value of the Required-Plugins header #! in your manifest_headers.cmake file. #! #! This function internally calls ctkMacroBuildPlugin() and adds support #! for Qt Help files and installers. #! #! Options: #! \param TEST_PLUGIN Mark this plug-in as a testing plug-in. #! \param NO_INSTALL Don't install this plug-in. #! #! Parameters: #! #! \param EXPORT_DIRECTIVE (required) The export directive to use in the generated #! _Exports.h file. #! #! Multi-value parameters (all optional): #! #! \param EXPORTED_INCLUDE_SUFFIXES A list of sub-directories which should #! be added to the current source directory. The resulting directories #! will be available in the set of include directories of depending plug-ins. #! \param MODULE_DEPENDS (optional) A list of Modules this plug-in depends on. #! \param PACKAGE_DEPENDS (optional) A list of external packages this plug-in depends on. #! \param DOXYGEN_TAGFILES (optional) Which external tag files should be available for the plugin documentation #! \param MOC_OPTIONS (optional) Additional options to pass to the Qt MOC compiler #! \param WARNINGS_NO_ERRORS (optional) Do not handle compiler warnings as errors function(mitk_create_plugin) # options set(arg_options TEST_PLUGIN # Mark this plug-in as a testing plug-in NO_INSTALL # Don't install this plug-in NO_QHP_TRANSFORM WARNINGS_NO_ERRORS ) # single value arguments set(arg_single EXPORT_DIRECTIVE # (required) TODO: could be generated via CMake as it is done for MITK modules already ) # multiple value arguments set(arg_multiple EXPORTED_INCLUDE_SUFFIXES # (optional) additional public include directories MODULE_DEPENDS # (optional) PACKAGE_DEPENDS DOXYGEN_TAGFILES MOC_OPTIONS SUBPROJECTS ) cmake_parse_arguments(_PLUGIN "${arg_options}" "${arg_single}" "${arg_multiple}" ${ARGN}) if(_PLUGIN_TEST_PLUGIN) set(_PLUGIN_NO_INSTALL 1) set(is_test_plugin "TEST_PLUGIN") else() set(is_test_plugin) endif() set(_PLUGIN_MOC_OPTIONS "-DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED ${_PLUGIN_MOC_OPTIONS}") set(PLUGIN_TARGET ${PROJECT_NAME}) mitk_check_module_dependencies(MODULES ${_PLUGIN_MODULE_DEPENDS} PACKAGES ${_PLUGIN_PACKAGE_DEPENDS} MISSING_DEPENDENCIES_VAR _missing_deps MODULE_DEPENDENCIES_VAR _module_deps PACKAGE_DEPENDENCIES_VAR _package_deps) if(_missing_deps) if(NOT MITK_BUILD_ALL_PLUGINS) message(SEND_ERROR "${PROJECT_NAME} is missing requirements and won't be built. Missing: ${_missing_deps}") else() message(STATUS "${PROJECT_NAME} is missing requirements and won't be built. Missing: ${_missing_deps}") endif() return() endif() # -------------- All dependencies are resolved ------------------ message(STATUS "Creating CTK plugin ${PROJECT_NAME}") include(files.cmake) set(_PLUGIN_CPP_FILES ${CPP_FILES}) set(_PLUGIN_MOC_H_FILES ${MOC_H_FILES}) set(_PLUGIN_UI_FILES ${UI_FILES}) set(_PLUGIN_CACHED_RESOURCE_FILES ${CACHED_RESOURCE_FILES}) set(_PLUGIN_TRANSLATION_FILES ${TRANSLATION_FILES}) set(_PLUGIN_QRC_FILES ${QRC_FILES}) set(_PLUGIN_H_FILES ${H_FILES}) set(_PLUGIN_TXX_FILES ${TXX_FILES}) set(_PLUGIN_DOX_FILES ${DOX_FILES}) set(_PLUGIN_CMAKE_FILES ${CMAKE_FILES} files.cmake) set(_PLUGIN_FILE_DEPENDENCIES ${FILE_DEPENDENCIES}) if(CTK_PLUGINS_OUTPUT_DIR) set(_output_dir "${CTK_PLUGINS_OUTPUT_DIR}") else() set(_output_dir "") endif() # Compute the plugin dependencies ctkFunctionGetTargetLibraries(_PLUGIN_target_libraries "") #------------------------------------------------------------# #------------------ Qt Help support -------------------------# set(PLUGIN_GENERATED_QCH_FILES ) if(BLUEBERRY_USE_QT_HELP AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/documentation/UserManual") set(PLUGIN_DOXYGEN_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/documentation/UserManual") set(PLUGIN_DOXYGEN_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/documentation/UserManual") # Create a list of Doxygen tag files from the plug-in dependencies set(PLUGIN_DOXYGEN_TAGFILES) foreach(_dep_target ${_PLUGIN_target_libraries}) string(REPLACE _ . _dep ${_dep_target}) get_target_property(_is_imported ${_dep_target} IMPORTED) if(_is_imported) get_target_property(_import_loc_debug ${_dep_target} IMPORTED_LOCATION_DEBUG) get_target_property(_import_loc_release ${_dep_target} IMPORTED_LOCATION_RELEASE) # There is not necessarily a debug and release build if(_import_loc_release) set(_import_loc ${_import_loc_release}) else() set(_import_loc ${_import_loc_debug}) endif() get_filename_component(_target_filename "${_import_loc}" NAME) # on windows there might be a Debug or Release subdirectory string(REGEX REPLACE "/bin/plugins/(Debug/|Release/)?${_target_filename}" "/Plugins/${_dep}/documentation/UserManual" plugin_tag_dir "${_import_loc}" ) else() set(plugin_tag_dir "${CMAKE_BINARY_DIR}/Plugins/${_dep}/documentation/UserManual") endif() set(_tag_file "${plugin_tag_dir}/${_dep_target}.tag") if(EXISTS ${_tag_file}) set(PLUGIN_DOXYGEN_TAGFILES "${PLUGIN_DOXYGEN_TAGFILES} \"${_tag_file}=qthelp://${_dep}/bundle/\"") endif() endforeach() if(_PLUGIN_DOXYGEN_TAGFILES) set(PLUGIN_DOXYGEN_TAGFILES "${PLUGIN_DOXYGEN_TAGFILES} ${_PLUGIN_DOXYGEN_TAGFILES}") endif() #message("PLUGIN_DOXYGEN_TAGFILES: ${PLUGIN_DOXYGEN_TAGFILES}") if(_PLUGIN_NO_QHP_TRANSFORM) set(_use_qhp_xsl 0) else() set(_use_qhp_xsl 1) endif() _FUNCTION_CREATE_CTK_QT_COMPRESSED_HELP(PLUGIN_GENERATED_QCH_FILES ${_use_qhp_xsl}) list(APPEND _PLUGIN_CACHED_RESOURCE_FILES ${PLUGIN_GENERATED_QCH_FILES}) endif() #------------------------------------------------------------# #------------------ Create Plug-in --------------------------# mitkFunctionOrganizeSources( SOURCE ${_PLUGIN_CPP_FILES} HEADER ${_PLUGIN_H_FILES} TXX ${_PLUGIN_TXX_FILES} DOC ${_PLUGIN_DOX_FILES} UI ${_PLUGIN_UI_FILES} QRC ${_PLUGIN_QRC_FILES} ${_PLUGIN_CACHED_RESOURCE_FILES} META ${_PLUGIN_META_FILES} MOC ${MY_MOC_CPP} GEN_UI ${MY_UI_CPP} GEN_QRC ${MY_QRC_SRCS} ) ctkMacroBuildPlugin( NAME ${PLUGIN_TARGET} EXPORT_DIRECTIVE ${_PLUGIN_EXPORT_DIRECTIVE} SRCS ${_PLUGIN_CPP_FILES} ${_PLUGIN_H_FILES} ${CORRESPONDING__H_FILES} ${GLOBBED__H_FILES} MOC_SRCS ${_PLUGIN_MOC_H_FILES} MOC_OPTIONS ${_PLUGIN_MOC_OPTIONS} UI_FORMS ${_PLUGIN_UI_FILES} EXPORTED_INCLUDE_SUFFIXES ${_PLUGIN_EXPORTED_INCLUDE_SUFFIXES} RESOURCES ${_PLUGIN_QRC_FILES} TARGET_LIBRARIES ${_PLUGIN_target_libraries} CACHED_RESOURCEFILES ${_PLUGIN_CACHED_RESOURCE_FILES} TRANSLATIONS ${_PLUGIN_TRANSLATION_FILES} OUTPUT_DIR ${_output_dir} NO_INSTALL # we install the plug-in ourselves ${is_test_plugin} ) mitk_use_modules(TARGET ${PLUGIN_TARGET} MODULES ${_PLUGIN_MODULE_DEPENDS} PACKAGES ${_PLUGIN_PACKAGE_DEPENDS} ) set_property(TARGET ${PLUGIN_TARGET} APPEND PROPERTY COMPILE_DEFINITIONS US_MODULE_NAME=${PLUGIN_TARGET}) set_property(TARGET ${PLUGIN_TARGET} PROPERTY US_MODULE_NAME ${PLUGIN_TARGET}) set(plugin_c_flags) set(plugin_cxx_flags) if(NOT _PLUGIN_WARNINGS_NO_ERRORS) if(MSVC_VERSION) mitkFunctionCheckCAndCXXCompilerFlags("/WX" plugin_c_flags plugin_cxx_flags) else() mitkFunctionCheckCAndCXXCompilerFlags(-Werror plugin_c_flags plugin_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" plugin_c_flags plugin_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=static-member-init" plugin_c_flags plugin_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unknown-warning" plugin_c_flags plugin_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=gnu" plugin_c_flags plugin_cxx_flags) mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=inconsistent-missing-override" plugin_c_flags plugin_cxx_flags) endif() endif() if(plugin_c_flags) string(REPLACE " " ";" plugin_c_flags "${plugin_c_flags}") target_compile_options(${PLUGIN_TARGET} PRIVATE ${plugin_c_flags}) endif() if(plugin_cxx_flags) string(REPLACE " " ";" plugin_cxx_flags "${plugin_cxx_flags}") target_compile_options(${PLUGIN_TARGET} PRIVATE ${plugin_cxx_flags}) endif() - if(MITK_DEFAULT_SUBPROJECTS AND NOT MY_SUBPROJECTS) - set(MY_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS}) + if(NOT MY_SUBPROJECTS) + if(MITK_DEFAULT_SUBPROJECTS) + set(MY_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS}) + else() + set(MY_SUBPROJECTS MITK-Plugins) + endif() endif() if(MY_SUBPROJECTS) set_property(TARGET ${PLUGIN_TARGET} PROPERTY LABELS ${MY_SUBPROJECTS}) foreach(subproject ${MY_SUBPROJECTS}) add_dependencies(${subproject} ${PLUGIN_TARGET}) endforeach() endif() if(_PLUGIN_TEST_PLUGIN) find_package(CppUnit REQUIRED) target_include_directories(${PLUGIN_TARGET} PRIVATE ${CppUnit_INCLUDE_DIRS}) target_link_libraries(${PLUGIN_TARGET} PRIVATE ${CppUnit_LIBRARIES}) endif() if(mbilog_FOUND) target_link_libraries(${PLUGIN_TARGET} PRIVATE mbilog) endif() set(_PLUGIN_META_FILES "${CMAKE_CURRENT_SOURCE_DIR}/manifest_headers.cmake") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plugin.xml") list(APPEND _PLUGIN_META_FILES "${CMAKE_CURRENT_SOURCE_DIR}/plugin.xml") endif() set(PLUGIN_TARGET ${PLUGIN_TARGET} PARENT_SCOPE) #------------------------------------------------------------# #------------------ Installer support -----------------------# if(NOT _PLUGIN_NO_INSTALL) set(install_directories "") if(NOT MACOSX_BUNDLE_NAMES) set(install_directories bin/plugins) else(NOT MACOSX_BUNDLE_NAMES) foreach(bundle_name ${MACOSX_BUNDLE_NAMES}) list(APPEND install_directories ${bundle_name}.app/Contents/MacOS/plugins) endforeach(bundle_name) endif(NOT MACOSX_BUNDLE_NAMES) foreach(install_subdir ${install_directories}) mitkFunctionInstallCTKPlugin(TARGETS ${PLUGIN_TARGET} DESTINATION ${install_subdir}) endforeach() set(_autoload_targets ) foreach(_dependency ${_module_deps}) get_target_property(_dep_autoloads ${_dependency} MITK_AUTOLOAD_TARGETS) if (_dep_autoloads) list(APPEND _autoload_targets ${_dep_autoloads}) endif() endforeach() # The MITK_AUTOLOAD_TARGETS property is used in the mitkFunctionInstallAutoLoadModules # macro which expects a list of plug-in targets. if (_autoload_targets) list(REMOVE_DUPLICATES _autoload_targets) set_target_properties(${PLUGIN_TARGET} PROPERTIES MITK_AUTOLOAD_TARGETS "${_autoload_targets}") endif() endif() endfunction() function(_FUNCTION_CREATE_CTK_QT_COMPRESSED_HELP qch_file use_xsl) set(_manifest_path "${CMAKE_CURRENT_SOURCE_DIR}/manifest_headers.cmake") if(NOT EXISTS ${_manifest_path}) message(FATAL_ERROR "${_manifest_path} not found") endif() include(${_manifest_path}) string(REPLACE "_" "." Plugin-SymbolicName "${PLUGIN_TARGET}") configure_file(${MITK_SOURCE_DIR}/Documentation/doxygen_plugin_manual.conf.in ${PLUGIN_DOXYGEN_OUTPUT_DIR}/doxygen.conf ) set(_qhp_xsl_file "${MITK_SOURCE_DIR}/Documentation/qhp_toc.xsl") set(_generated_qhp_file "${PLUGIN_DOXYGEN_OUTPUT_DIR}/html/index.qhp") set(_transformed_qhp_file "${PLUGIN_DOXYGEN_OUTPUT_DIR}/html/${PLUGIN_TARGET}.qhp") set(${qch_file} "${CMAKE_CURRENT_BINARY_DIR}/resources/${PLUGIN_TARGET}.qch") set(_xsl_command ) if(use_xsl) set(_xsl_command COMMAND ${QT_XMLPATTERNS_EXECUTABLE} ${_qhp_xsl_file} ${_generated_qhp_file} -output ${_transformed_qhp_file}) endif() file(GLOB _file_dependencies "${PLUGIN_DOXYGEN_INPUT_DIR}/*") add_custom_command(OUTPUT ${${qch_file}} # Generate a Qt help project (index.qhp) with doxygen COMMAND ${DOXYGEN_EXECUTABLE} ${PLUGIN_DOXYGEN_OUTPUT_DIR}/doxygen.conf # Use a XSL transformation to get rid of the top-level entry ${_xsl_command} # Generate the final Qt compressed help file (.qch) COMMAND ${QT_HELPGENERATOR_EXECUTABLE} ${_transformed_qhp_file} -o ${${qch_file}} DEPENDS ${PLUGIN_DOXYGEN_OUTPUT_DIR}/doxygen.conf ${_file_dependencies} ) #set_source_files_properties(${qch_file} PROPERTIES GENERATED 1) set(${qch_file} ${${qch_file}} PARENT_SCOPE) endfunction() function(MACRO_CREATE_MITK_CTK_PLUGIN) message(SEND_ERROR "The function MACRO_CREATE_MITK_CTK_PLUGIN was renamed to mitk_create_plugin in MITK 2015.05.") endfunction() diff --git a/CMake/mitkFunctionWhitelists.cmake b/CMake/mitkFunctionWhitelists.cmake index ec6b239556..b023743a79 100644 --- a/CMake/mitkFunctionWhitelists.cmake +++ b/CMake/mitkFunctionWhitelists.cmake @@ -1,244 +1,244 @@ ############################################################################### # # mitkFunctionCreateWhitelistPaths # #! Creates advanced cache variables for setting the internal and external #! whitelist directories. #! #! USAGE: #! #! \code #! mitkFunctionCreateWhitelistPaths() #! \endcode #! #! The parameter specifies the prefix used for the created variables #! _WHITELISTS_INTERNAL_PATH and _WHITELISTS_EXTERNAL_PATH. #! #! Default values: #! _WHITELISTS_INTERNAL_PATH = _SOURCE_DIR/CMake/Whitelists #! _WHITELISTS_EXTERNAL_PATH = %HOME%/.mitk/Whitelists #! #! List of variables available after the function is called: #! - _WHITELISTS_INTERNAL_PATH #! - _WHITELISTS_EXTERNAL_PATH #! #! Parameters: #! \param The prefix of the created cache variables. # ############################################################################### function(mitkFunctionCreateWhitelistPaths) set(${ARGV0}_WHITELISTS_INTERNAL_PATH "${${ARGV0}_SOURCE_DIR}/CMake/Whitelists" CACHE PATH "") set(${ARGV0}_WHITELISTS_EXTERNAL_PATH ".mitk/Whitelists") if(WIN32) set(${ARGV0}_WHITELISTS_EXTERNAL_PATH "$ENV{HOMEDRIVE}$ENV{HOMEPATH}/${${ARGV0}_WHITELISTS_EXTERNAL_PATH}") else() set(${ARGV0}_WHITELISTS_EXTERNAL_PATH "$ENV{HOME}/${${ARGV0}_WHITELISTS_EXTERNAL_PATH}") endif() FILE(TO_CMAKE_PATH "${${ARGV0}_WHITELISTS_EXTERNAL_PATH}" ${ARGV0}_WHITELISTS_EXTERNAL_PATH) set(${ARGV0}_WHITELISTS_EXTERNAL_PATH "${${ARGV0}_WHITELISTS_EXTERNAL_PATH}" CACHE PATH "") mark_as_advanced( ${ARGV0}_WHITELISTS_INTERNAL_PATH ${ARGV0}_WHITELISTS_EXTERNAL_PATH ) endfunction() ############################################################################### # # mitkFunctionFindWhitelists # #! Adds all whitelists found in specfied whitelist paths to the advanced cache #! variable _WHITELIST as enumeration entries. #! #! USAGE: #! #! \code #! mitkFunctionFindWhitelists() #! \endcode #! #! The parameter specifies the prefix used for the created #! cache variable _WHITELIST. Its default value is "None". #! The function mitkFunctionCreateWhitelistPaths must be called #! with the same prior to this function. #! #! Whitelists are *.cmake files which set the two list variables #! enabled_modules and enabled_plugins. #! #! List of variables available after the function is called: #! - _WHITELIST #! #! \sa mitkFunctionCreateWhitelistPaths #! #! Parameters: #! \param The prefix of the created cache variable. # ############################################################################### function(mitkFunctionFindWhitelists) set(whitelists "None") file(GLOB internalWhitelistFiles "${${ARGV0}_WHITELISTS_INTERNAL_PATH}/*.cmake") foreach(whitelistFile ${internalWhitelistFiles}) get_filename_component(whitelistFile "${whitelistFile}" NAME_WE) list(APPEND whitelists "${whitelistFile}") endforeach() file(GLOB externalWhitelistFiles "${${ARGV0}_WHITELISTS_EXTERNAL_PATH}/*.cmake") foreach(whitelistFile ${externalWhitelistFiles}) get_filename_component(whitelistFile "${whitelistFile}" NAME_WE) list(APPEND whitelists "${whitelistFile} (external)") endforeach() set(${ARGV0}_WHITELIST "None" CACHE STRING "") set_property(CACHE ${ARGV0}_WHITELIST PROPERTY STRINGS ${whitelists}) mark_as_advanced(${ARGV0}_WHITELIST) endfunction() ############################################################################### # # mitkFunctionWhitelistModules # #! Only enables modules which are present in the currently set whitelist or #! all modules if no whitelist is specified at all. #! #! USAGE: #! #! \code #! set( #! ModuleDir #! AnotherModuleDir #! ... #! ) #! mitkFunctionWhitelistModules( ) #! \endcode #! #! The parameter specifies the prefix used to get the #! currently set whitelist from _WHITELIST. Both functions #! mitkFunctionCreateWhitelistPaths and mitkFunctionFindWhitelists #! must be called with the same prior to this function. #! The list must contain the module directory names instead #! of the module names itself, as the entries are used in #! add_directory calls. #! #! \sa mitkFunctionCreateWhitelistPaths #! \sa mitkFunctionFindWhitelists #! #! Parameters: #! \param The prefix of the white list cache variable. #! \param The module directory list variable. # ############################################################################### function(mitkFunctionWhitelistModules) if(${ARGV0}_WHITELIST STREQUAL "None") foreach(module ${${ARGV1}}) - add_subdirectory(${module}) + add_subdirectory(Modules/${module}) endforeach() else() string(FIND "${${ARGV0}_WHITELIST}" " (external)" index REVERSE) if(${index} EQUAL -1) set(whitelistFile "${${ARGV0}_WHITELISTS_INTERNAL_PATH}/${${ARGV0}_WHITELIST}.cmake") else() string(SUBSTRING "${${ARGV0}_WHITELIST}" 0 ${index} whitelistFile) set(whitelistFile "${${ARGV0}_WHITELISTS_EXTERNAL_PATH}/${whitelistFile}.cmake") endif() include(${whitelistFile}) if(NOT DEFINED enabled_modules) message(FATAL_ERROR "Variable 'enabled_modules' not set in whitelist file '${whitelistFile}'!") endif() foreach(module ${${ARGV1}}) list(FIND enabled_modules ${module} index) if(NOT index EQUAL -1) add_subdirectory(${module}) endif() endforeach() endif() endfunction() ############################################################################### # # mitkFunctionWhitelistPlugins # #! Only enables plugins which are present in the currently set whitelist or #! all plugins if no whitelist is specified at all. #! #! USAGE: #! #! \code #! set( #! org.example.plugin:OFF #! org.example.another.plugin:ON #! ... #! ) #! mitkFunctionWhitelistPlugins( ) #! \endcode #! #! The parameter specifies the prefix used to get the #! currently set whitelist from _WHITELIST. Both functions #! mitkFunctionCreateWhitelistPaths and mitkFunctionFindWhitelists #! must be called with the same prior to this function. #! The list must contain the plugin names. This function #! removes plugins not found in the currently set whitelist from #! the variable. Note that plugins which are OFF by #! default are not switched on. #! #! \sa mitkFunctionCreateWhitelistPaths #! \sa mitkFunctionFindWhitelists #! #! Parameters: #! \param The prefix of the white list cache variable. #! \param The plugin list variable to be modified. # ############################################################################### function(mitkFunctionWhitelistPlugins) if(${ARGV0}_WHITELIST STREQUAL "None") return() endif() string(FIND "${${ARGV0}_WHITELIST}" " (external)" index REVERSE) if(${index} EQUAL -1) set(whitelistFile "${${ARGV0}_WHITELISTS_INTERNAL_PATH}/${${ARGV0}_WHITELIST}.cmake") else() string(SUBSTRING "${${ARGV0}_WHITELIST}" 0 ${index} whitelistFile) set(whitelistFile "${${ARGV0}_WHITELISTS_EXTERNAL_PATH}/${whitelistFile}.cmake") endif() include(${whitelistFile}) if(NOT DEFINED enabled_plugins) message(FATAL_ERROR "Variable 'enabled_plugins' not set in whitelist file '${whitelistFile}'!") endif() set(plugins "") foreach(plugin ${${ARGV1}}) string(FIND ${plugin} ":" index REVERSE) if (NOT index EQUAL -1) string(SUBSTRING ${plugin} 0 ${index} _plugin) else() set(_plugin ${plugin}) endif() list(FIND enabled_plugins ${_plugin} index) if(NOT index EQUAL -1) list(APPEND plugins ${plugin}) endif() endforeach() set(${ARGV1} ${plugins} PARENT_SCOPE) endfunction() diff --git a/CMakeExternals/ExternalProjectList.cmake b/CMakeExternals/ExternalProjectList.cmake new file mode 100644 index 0000000000..531b51119a --- /dev/null +++ b/CMakeExternals/ExternalProjectList.cmake @@ -0,0 +1,44 @@ +mitkFunctionAddExternalProject(NAME Poco ON COMPONENTS Foundation Net Util XML Zip) +mitkFunctionAddExternalProject(NAME DCMTK ON DOC "EXPERIMENTAL, superbuild only: Use DCMTK in MITK") +mitkFunctionAddExternalProject(NAME OpenIGTLink OFF) + +mitkFunctionAddExternalProject(NAME tinyxml ON ADVANCED) +mitkFunctionAddExternalProject(NAME GDCM ON ADVANCED) +mitkFunctionAddExternalProject(NAME GLUT OFF ADVANCED) +mitkFunctionAddExternalProject(NAME Raptor2 OFF ADVANCED) +mitkFunctionAddExternalProject(NAME Eigen ON ADVANCED DOC "Use the Eigen library") +mitkFunctionAddExternalProject(NAME ANN ON ADVANCED DOC "Use Approximate Nearest Neighbor Library") +mitkFunctionAddExternalProject(NAME CppUnit ON ADVANCED DOC "Use CppUnit for unit tests") + +mitkFunctionAddExternalProject(NAME PCRE OFF ADVANCED NO_PACKAGE) +mitkFunctionAddExternalProject(NAME ZLIB OFF ADVANCED NO_PACKAGE NO_CACHE) + +mitkFunctionAddExternalProject(NAME HDF5 ON ADVANCED) + +# ----------------------------------------- +# The following external projects must be +# ordered according to their +# inter-dependencies + +mitkFunctionAddExternalProject(NAME SWIG OFF ADVANCED NO_PACKAGE DEPENDS PCRE) +mitkFunctionAddExternalProject(NAME Python OFF NO_PACKAGE DEPENDS SWIG DOC "Use Python wrapping in MITK") +mitkFunctionAddExternalProject(NAME Numpy OFF ADVANCED NO_PACKAGE) +mitkFunctionAddExternalProject(NAME OpenCV OFF) +mitkFunctionAddExternalProject(NAME Vigra OFF DEPENDS HDF5) + +# These are "hard" dependencies and always set to ON +mitkFunctionAddExternalProject(NAME ITK ON NO_CACHE DEPENDS HDF5) +mitkFunctionAddExternalProject(NAME VTK ON NO_CACHE) +mitkFunctionAddExternalProject(NAME Boost ON NO_CACHE) + +mitkFunctionAddExternalProject(NAME SimpleITK OFF DEPENDS ITK GDCM SWIG) +mitkFunctionAddExternalProject(NAME ACVD OFF DOC "Use Approximated Centroidal Voronoi Diagrams") +mitkFunctionAddExternalProject(NAME CTK ON DEPENDS Qt5 DCMTK DOC "Use CTK in MITK") +mitkFunctionAddExternalProject(NAME Rasqal OFF DEPENDS Raptor2 PCRE ADVANCED) +mitkFunctionAddExternalProject(NAME Redland OFF DEPENDS Rasqal DOC "Use the Redland RDF library") +mitkFunctionAddExternalProject(NAME DCMQI OFF DEPENDS DCMTK ITK DOC "Use dcmqi in MITK") +mitkFunctionAddExternalProject(NAME MatchPoint OFF ADVANCED DEPENDS ITK DOC "Use the MatchPoint translation image registration library") + +if(MITK_USE_Qt5) + mitkFunctionAddExternalProject(NAME Qwt ON ADVANCED DEPENDS Qt5) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e67b4e865..b1fa900508 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,1350 +1,1348 @@ set(MITK_CMAKE_MINIMUM_REQUIRED_VERSION 3.5) cmake_minimum_required(VERSION ${MITK_CMAKE_MINIMUM_REQUIRED_VERSION}) #----------------------------------------------------------------------------- # See http://www.cmake.org/cmake/help/v3.5/manual/cmake-policies.7.html for details #----------------------------------------------------------------------------- set(project_policies ) foreach(policy ${project_policies}) if(POLICY ${policy}) cmake_policy(SET ${policy} NEW) endif() endforeach() +#----------------------------------------------------------------------------- +# MITK Extension Feature +#----------------------------------------------------------------------------- + +set(MITK_EXTENSION_DIRS "" CACHE STRING "") +mark_as_advanced(MITK_EXTENSION_DIRS) + #----------------------------------------------------------------------------- # Superbuild Option - Enabled by default #----------------------------------------------------------------------------- option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON) if(MITK_USE_SUPERBUILD) project(MITK-superbuild) set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR}) set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR}) else() project(MITK VERSION 2016.11.99) + include_directories(SYSTEM ${MITK_SUPERBUILD_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Update CMake module path -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------- set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake) -set(CMAKE_MODULE_PATH - ${MITK_CMAKE_DIR} - ${CMAKE_MODULE_PATH} - ) +set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR}) + +foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + set(MITK_CMAKE_EXTENSION_DIR ${MITK_EXTENSION_DIR}/CMake) + get_filename_component(MITK_CMAKE_EXTENSION_DIR ${MITK_CMAKE_EXTENSION_DIR} ABSOLUTE) + if(EXISTS ${MITK_CMAKE_EXTENSION_DIR}) + list(APPEND CMAKE_MODULE_PATH ${MITK_CMAKE_EXTENSION_DIR}) + endif() +endforeach() #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- # Standard CMake macros include(FeatureSummary) include(CTestUseLaunchers) include(CMakeParseArguments) include(FindPackageHandleStandardArgs) # MITK macros include(mitkFunctionGetGccVersion) include(mitkFunctionCheckCompilerFlags) include(mitkFunctionSuppressWarnings) # includes several functions include(mitkMacroEmptyExternalProject) include(mitkFunctionGenerateProjectXml) include(mitkFunctionEnableBuildConfiguration) include(mitkFunctionWhitelists) include(mitkFunctionAddExternalProject) SUPPRESS_VC_DEPRECATED_WARNINGS() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # Check miminum Mac OS X version #----------------------------------------------------------------------------- # The minimum supported Mac OS X version is 10.9. If you use a version less than 10.9, there is no guarantee that the build still works. if(APPLE) exec_program(sw_vers ARGS -productVersion OUTPUT_VARIABLE osx_version) if (osx_version VERSION_LESS "10.9") message(WARNING "Detected OS X version \"${osx_version}\" is not supported anymore. Minimum required OS X version is 10.9 or greater.") endif() if (CMAKE_OSX_DEPLOYMENT_TARGET AND CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.9) message(WARNING "Detected OS X deployment target \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" is not supported anymore. Minimum required OS X version is 10.9 or greater.") endif() endif() #----------------------------------------------------------------------------- # Check miminum compiler versions #----------------------------------------------------------------------------- if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") # require at least gcc 4.9 as provided by ppa:ubuntu-toolchain-r/test for Ubuntu 14.04 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) message(FATAL_ERROR "GCC version must be at least 4.9 If you are using Ubuntu 14.04, you can easily install gcc and g++ 4.9 (or any later version available) in addition to your version ${CMAKE_CXX_COMPILER_VERSION}: sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-4.9 g++-4.9 Make sure to explicitly specify these compilers when configuring MITK: CMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-4.9 CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-4.9 For more information on the proposed PPA see the Toolchain Updates section of https://wiki.ubuntu.com/ToolChain.") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # require at least clang 3.4 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) message(FATAL_ERROR "Clang version must be at least 3.4") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") # require at least clang 5.0 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "Apple Clang version must be at least 5.0") endif() elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # require at least Visual Studio 2015 if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19) message(FATAL_ERROR "Microsoft Visual Studio 2015 Update 3 or newer required") endif() else() message(WARNING "You are using an unsupported compiler! Compilation has only been tested with Clang (Linux or Apple), GCC and MSVC.") endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) else() set(GCC_VERSION 0) endif() set(MITK_CXX_STANDARD 14) set(CMAKE_CXX_EXTENSIONS 0) set(CMAKE_CXX_STANDARD ${MITK_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED 1) # This is necessary to avoid problems with compile feature checks. # CMAKE_CXX_STANDARD seems to only set the -std=c++14 flag for targets. # However, compile flag checks also need to be done with -std=c++14. # The MITK_CXX14_FLAG variable is also used for external projects # build during the MITK super-build. mitkFunctionCheckCompilerFlags("-std=c++14" MITK_CXX14_FLAG) #----------------------------------------------------------------------------- # Warn if source or build path is too long #----------------------------------------------------------------------------- if(WIN32) set(_src_dir_length_max 50) set(_bin_dir_length_max 50) if(MITK_USE_SUPERBUILD) set(_src_dir_length_max 34) # _src_dir_length_max - strlen(ep/src/ITK-build) set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build) endif() string(LENGTH "${MITK_SOURCE_DIR}" _src_n) string(LENGTH "${MITK_BINARY_DIR}" _bin_n) # The warnings should be converted to errors if(_src_n GREATER _src_dir_length_max) message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})." "Please move the MITK source code directory to a directory with a shorter path." ) endif() if(_bin_n GREATER _bin_dir_length_max) message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})." "Please move the MITK build directory to a directory with a shorter path." ) endif() endif() #----------------------------------------------------------------------------- # Additional MITK Options (also shown during superbuild) #----------------------------------------------------------------------------- macro(env_option name doc value) set(_value $ENV{${name}}) if("${_value}" STREQUAL "") set(_value ${value}) endif() option(${name} "${doc}" ${_value}) endmacro() # ----------------------------------------- # General build options option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON) option(WITH_COVERAGE "Enable/Disable coverage" OFF) option(BUILD_TESTING "Test the project" ON) env_option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF) env_option(MITK_BUILD_EXAMPLES "Build the MITK Examples" OFF) option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON) mark_as_advanced(MITK_BUILD_ALL_APPS MITK_ENABLE_PIC_READER ) # ----------------------------------------- # Qt version related variables env_option(MITK_USE_Qt5 "Use Qt 5 library" ON) env_option(MITK_USE_Qt5_WebEngine "Use Qt 5 WebEngine library" ON) if(MITK_USE_Qt5) set(MITK_QT5_MINIMUM_VERSION 5.6.0) set(MITK_QT5_COMPONENTS Concurrent OpenGL PrintSupport Script Sql Svg Widgets Xml XmlPatterns UiTools Help LinguistTools) if(MITK_USE_Qt5_WebEngine) set(MITK_QT5_COMPONENTS ${MITK_QT5_COMPONENTS} WebEngineWidgets) endif() if(APPLE) set(MITK_QT5_COMPONENTS ${MITK_QT5_COMPONENTS} DBus) endif() find_package(Qt5 ${MITK_QT5_MINIMUM_VERSION} COMPONENTS ${MITK_QT5_COMPONENTS} REQUIRED) if(Qt5_DIR) get_filename_component(_Qt5_DIR "${Qt5_DIR}/../../../" ABSOLUTE) list(FIND CMAKE_PREFIX_PATH "${_Qt5_DIR}" _result) if(_result LESS 0) set(CMAKE_PREFIX_PATH "${_Qt5_DIR};${CMAKE_PREFIX_PATH}" CACHE PATH "" FORCE) endif() endif() elseif(MITK_USE_Qt5_WebEngine) set(MITK_USE_Qt5_WebEngine OFF) endif() -# ------------------------------------------------------------------------ -# Register external projects which can be build with the MITK superbuild -# system. Each mitkFunctionAddExternalProject() call registers an external -# project for which a CMakeExternals/.cmake file must exist. The -# call also creates a MITK_USE_ variable (appearing in the CMake -# UI if the NO_CACHE option is *not* given). - - -# ----------------------------------------- -# Optional external projects with no -# inter-dependencies - set_property(GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS "") -mitkFunctionAddExternalProject(NAME Poco ON COMPONENTS Foundation Net Util XML Zip) -mitkFunctionAddExternalProject(NAME DCMTK ON DOC "EXPERIMENTAL, superbuild only: Use DCMTK in MITK") -mitkFunctionAddExternalProject(NAME OpenIGTLink OFF) - -mitkFunctionAddExternalProject(NAME tinyxml ON ADVANCED) -mitkFunctionAddExternalProject(NAME GDCM ON ADVANCED) -mitkFunctionAddExternalProject(NAME GLUT OFF ADVANCED) -mitkFunctionAddExternalProject(NAME Raptor2 OFF ADVANCED) -mitkFunctionAddExternalProject(NAME Eigen ON ADVANCED DOC "Use the Eigen library") -mitkFunctionAddExternalProject(NAME ANN ON ADVANCED DOC "Use Approximate Nearest Neighbor Library") -mitkFunctionAddExternalProject(NAME CppUnit ON ADVANCED DOC "Use CppUnit for unit tests") - -mitkFunctionAddExternalProject(NAME PCRE OFF ADVANCED NO_PACKAGE) -mitkFunctionAddExternalProject(NAME ZLIB OFF ADVANCED NO_PACKAGE NO_CACHE) - -mitkFunctionAddExternalProject(NAME HDF5 ON ADVANCED) +include(CMakeExternals/ExternalProjectList.cmake) -# ----------------------------------------- -# The following external projects must be -# ordered according to their -# inter-dependencies - -mitkFunctionAddExternalProject(NAME SWIG OFF ADVANCED NO_PACKAGE DEPENDS PCRE) -mitkFunctionAddExternalProject(NAME Python OFF NO_PACKAGE DEPENDS SWIG DOC "Use Python wrapping in MITK") -mitkFunctionAddExternalProject(NAME Numpy OFF ADVANCED NO_PACKAGE) -mitkFunctionAddExternalProject(NAME OpenCV OFF) -mitkFunctionAddExternalProject(NAME Vigra OFF DEPENDS HDF5) - -# These are "hard" dependencies and always set to ON -mitkFunctionAddExternalProject(NAME ITK ON NO_CACHE DEPENDS HDF5) -mitkFunctionAddExternalProject(NAME VTK ON NO_CACHE) -mitkFunctionAddExternalProject(NAME Boost ON NO_CACHE) - -mitkFunctionAddExternalProject(NAME SimpleITK OFF DEPENDS ITK GDCM SWIG) -mitkFunctionAddExternalProject(NAME ACVD OFF DOC "Use Approximated Centroidal Voronoi Diagrams") -mitkFunctionAddExternalProject(NAME CTK ON DEPENDS Qt5 DCMTK DOC "Use CTK in MITK") -mitkFunctionAddExternalProject(NAME Rasqal OFF DEPENDS Raptor2 PCRE ADVANCED) -mitkFunctionAddExternalProject(NAME Redland OFF DEPENDS Rasqal DOC "Use the Redland RDF library") -mitkFunctionAddExternalProject(NAME DCMQI OFF DEPENDS DCMTK ITK DOC "Use dcmqi in MITK") -mitkFunctionAddExternalProject(NAME MatchPoint OFF ADVANCED DEPENDS ITK DOC "Use the MatchPoint translation image registration library") - -if(MITK_USE_Qt5) - mitkFunctionAddExternalProject(NAME Qwt ON ADVANCED DEPENDS Qt5) -endif() +foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + set(MITK_CMAKE_EXTERNALS_EXTENSION_DIR ${MITK_EXTENSION_DIR}/CMakeExternals) + get_filename_component(MITK_CMAKE_EXTERNALS_EXTENSION_DIR ${MITK_CMAKE_EXTERNALS_EXTENSION_DIR} ABSOLUTE) + if(EXISTS ${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/ExternalProjectList.cmake) + include(${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/ExternalProjectList.cmake) + endif() +endforeach() # ----------------------------------------- # Other MITK_USE_* options not related to # external projects build via the # MITK superbuild env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ON) env_option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF) #----------------------------------------------------------------------------- # Build configurations #----------------------------------------------------------------------------- set(_buildConfigs "Custom") file(GLOB _buildConfigFiles CMake/BuildConfigurations/*.cmake) foreach(_buildConfigFile ${_buildConfigFiles}) get_filename_component(_buildConfigFile ${_buildConfigFile} NAME_WE) list(APPEND _buildConfigs ${_buildConfigFile}) endforeach() set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations") set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS ${_buildConfigs}) mitkFunctionEnableBuildConfiguration() mitkFunctionCreateWhitelistPaths(MITK) mitkFunctionFindWhitelists(MITK) # ----------------------------------------- # Custom dependency logic option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF) set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries") # only windows can't build python in debug mode if(MITK_USE_Python AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND WIN32) message(WARNING "Disabling Python support. Building MITK Python in debug mode on Windowsis not supported!") set(MITK_USE_Python OFF CACHE BOOL "Use python wrapping in MITK" FORCE) set(MITK_USE_Numpy OFF CACHE BOOL "Use Numpy" FORCE) set(MITK_USE_SimpleITK OFF CACHE BOOL "Use SimpleITK" FORCE) elseif(MITK_USE_Python) set(MITK_USE_ZLIB ON) if(NOT MITK_USE_Numpy) message("> Forcing MITK_USE_Numpy to ON because of MITK_USE_Python") set(MITK_USE_Numpy ON CACHE BOOL "Use Numpy" FORCE) endif() if(NOT MITK_USE_SimpleITK) message("> Forcing MITK_USE_SimpleITK to ON because of MITK_USE_Python") set(MITK_USE_SimpleITK ON CACHE BOOL "Use SimpleITK" FORCE) endif() option(MITK_USE_SYSTEM_PYTHON "Use the system python runtime" OFF) if(MITK_USE_SYSTEM_PYTHON) find_package(PythonLibs REQUIRED) find_package(PythonInterp REQUIRED) endif() elseif(MITK_USE_Python AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" AND WIN32) message(WARNING "Disabling Python support. Building MITK Python in debug mode on Windowsis not supported!") set(MITK_USE_Python OFF CACHE BOOL "Use python wrapping in MITK" FORCE) endif() if(BUILD_TESTING AND NOT MITK_USE_CppUnit) message("> Forcing MITK_USE_CppUnit to ON because BUILD_TESTING=ON") set(MITK_USE_CppUnit ON CACHE BOOL "Use CppUnit for unit tests" FORCE) endif() if(MITK_USE_BLUEBERRY) option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF) mark_as_advanced(MITK_BUILD_ALL_PLUGINS) if(NOT MITK_USE_CTK) message("> Forcing MITK_USE_CTK to ON because of MITK_USE_BLUEBERRY") set(MITK_USE_CTK ON CACHE BOOL "Use CTK in MITK" FORCE) endif() endif() #----------------------------------------------------------------------------- # Pixel type multiplexing #----------------------------------------------------------------------------- # Customize the default pixel types for multiplex macros set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel, itk::RGBAPixel" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros") set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") mark_as_advanced(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS ) # consistency checks if(NOT MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES) set(MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES "int, unsigned int, short, unsigned short, char, unsigned char" CACHE STRING "List of integral pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES) set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES "double, float" CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES) set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES "itk::RGBPixel, itk::RGBAPixel" CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros" FORCE) endif() if(NOT MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) string(REPLACE "," ";" _integral_types ${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}) string(REPLACE "," ";" _floating_types ${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}) foreach(_scalar_type ${_integral_types} ${_floating_types}) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}itk::VariableLengthVector<${_scalar_type}>,") endforeach() string(LENGTH "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" _length) math(EXPR _length "${_length} - 1") string(SUBSTRING "${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}" 0 ${_length} MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES) set(MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES ${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} CACHE STRING "List of vector pixel types used in AccessByItk and InstantiateAccessFunction macros for itk::VectorImage types" FORCE) endif() if(NOT MITK_ACCESSBYITK_DIMENSIONS) set(MITK_ACCESSBYITK_DIMENSIONS "2,3" CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros") endif() #----------------------------------------------------------------------------- # Project.xml #----------------------------------------------------------------------------- # A list of topologically ordered targets set(CTEST_PROJECT_SUBPROJECTS) list(APPEND CTEST_PROJECT_SUBPROJECTS MITK-Core MITK-CoreUI MITK-IGT MITK-ToF MITK-DTI MITK-Modules # all modules not contained in a specific subproject MITK-Plugins # all plugins not contained in a specific subproject MITK-Examples Unlabeled # special "subproject" catching all unlabeled targets and tests ) # Configure CTestConfigSubProject.cmake that could be used by CTest scripts configure_file(${MITK_SOURCE_DIR}/CTestConfigSubProject.cmake.in ${MITK_BINARY_DIR}/CTestConfigSubProject.cmake) if(CTEST_PROJECT_ADDITIONAL_TARGETS) # those targets will be executed at the end of the ctest driver script # and they also get their own subproject label set(subproject_list "${CTEST_PROJECT_SUBPROJECTS};${CTEST_PROJECT_ADDITIONAL_TARGETS}") else() set(subproject_list "${CTEST_PROJECT_SUBPROJECTS}") endif() # Generate Project.xml file expected by the CTest driver script mitkFunctionGenerateProjectXml(${MITK_BINARY_DIR} MITK "${subproject_list}" ${MITK_USE_SUPERBUILD}) #----------------------------------------------------------------------------- # Superbuild script #----------------------------------------------------------------------------- if(MITK_USE_SUPERBUILD) include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake") # Print configuration summary message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL) return() endif() #***************************************************************************** #**************************** END OF SUPERBUILD **************************** #***************************************************************************** #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(WriteBasicConfigVersionFile) include(CheckCXXSourceCompiles) include(GenerateExportHeader) include(mitkFunctionAddCustomModuleTest) include(mitkFunctionCheckModuleDependencies) include(mitkFunctionCompileSnippets) include(mitkFunctionConfigureVisualStudioUserProjectFile) include(mitkFunctionConvertXPSchema) include(mitkFunctionCreateBlueBerryApplication) include(mitkFunctionCreateCommandLineApp) include(mitkFunctionCreateModule) include(mitkFunctionCreatePlugin) include(mitkFunctionCreateProvisioningFile) include(mitkFunctionGetLibrarySearchPaths) include(mitkFunctionGetVersion) include(mitkFunctionGetVersionDescription) include(mitkFunctionInstallAutoLoadModules) include(mitkFunctionInstallCTKPlugin) include(mitkFunctionInstallProvisioningFiles) include(mitkFunctionInstallThirdPartyCTKPlugins) include(mitkFunctionOrganizeSources) include(mitkFunctionTestPlugin) include(mitkFunctionUseModules) if( ${MITK_USE_MatchPoint} ) include(mitkFunctionCreateMatchPointDeployedAlgorithm) endif() include(mitkMacroConfigureItkPixelTypes) include(mitkMacroCreateExecutable) include(mitkMacroCreateModuleTests) include(mitkMacroGenerateToolsLibrary) include(mitkMacroGetLinuxDistribution) include(mitkMacroGetPMDPlatformString) include(mitkMacroInstall) include(mitkMacroInstallHelperApp) include(mitkMacroInstallTargets) include(mitkMacroMultiplexPicType) # Deprecated include(mitkMacroCreateCTKPlugin) #----------------------------------------------------------------------------- # Global CMake variables #----------------------------------------------------------------------------- # Required and enabled C++14 features for all MITK code. # These are added as PUBLIC compile features to all MITK modules. set(MITK_CXX_FEATURES cxx_auto_type cxx_decltype cxx_enum_forward_declarations cxx_extended_friend_declarations cxx_extern_templates cxx_final cxx_lambdas cxx_local_type_template_args cxx_long_long_type cxx_nullptr cxx_override cxx_range_for cxx_right_angle_brackets cxx_rvalue_references cxx_static_assert cxx_strong_enums cxx_template_template_parameters cxx_trailing_return_types cxx_variadic_macros ) if(NOT DEFINED CMAKE_DEBUG_POSTFIX) # We can't do this yet because the CTK Plugin Framework # cannot cope with a postfix yet. #set(CMAKE_DEBUG_POSTFIX d) endif() #----------------------------------------------------------------------------- # Output directories. #----------------------------------------------------------------------------- set(_default_LIBRARY_output_dir lib) set(_default_RUNTIME_output_dir bin) set(_default_ARCHIVE_output_dir lib) foreach(type LIBRARY RUNTIME ARCHIVE) # Make sure the directory exists if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}") endif() if(MITK_CMAKE_${type}_OUTPUT_DIRECTORY) set(CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}) else() set(CMAKE_${type}_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${_default_${type}_output_dir}) set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY}) endif() set(CMAKE_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY} CACHE INTERNAL "Output directory for ${type} files.") mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY) endforeach() #----------------------------------------------------------------------------- # Set MITK specific options and variables (NOT available during superbuild) #----------------------------------------------------------------------------- # Look for optional Doxygen package find_package(Doxygen) option(BLUEBERRY_DEBUG_SMARTPOINTER "Enable code for debugging smart pointers" OFF) mark_as_advanced(BLUEBERRY_DEBUG_SMARTPOINTER) # ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and mitkWorkbench option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON) mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW) # TODO: check if necessary option(USE_ITKZLIB "Use the ITK zlib for pic compression." ON) mark_as_advanced(USE_ITKZLIB) if(NOT MITK_FAST_TESTING) if(DEFINED MITK_CTEST_SCRIPT_MODE AND (MITK_CTEST_SCRIPT_MODE STREQUAL "continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "experimental") ) set(MITK_FAST_TESTING 1) endif() endif() if(NOT UNIX AND NOT MINGW) set(MITK_WIN32_FORCE_STATIC "STATIC" CACHE INTERNAL "Use this variable to always build static libraries on non-unix platforms") endif() if(MITK_BUILD_ALL_PLUGINS) set(MITK_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL") endif() # Configure pixel types used for ITK image access multiplexing mitkMacroConfigureItkPixelTypes() # Configure module naming conventions set(MITK_MODULE_NAME_REGEX_MATCH "^[A-Z].*$") set(MITK_MODULE_NAME_REGEX_NOT_MATCH "^[Mm][Ii][Tt][Kk].*$") set(MITK_MODULE_NAME_PREFIX "Mitk") set(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME 1) #----------------------------------------------------------------------------- # Get MITK version info #----------------------------------------------------------------------------- mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK) mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK) # MITK_VERSION set(MITK_VERSION_STRING "${MITK_VERSION_MAJOR}.${MITK_VERSION_MINOR}.${MITK_VERSION_PATCH}") if(MITK_VERSION_PATCH STREQUAL "99") set(MITK_VERSION_STRING "${MITK_VERSION_STRING}-${MITK_REVISION_SHORTID}") endif() #----------------------------------------------------------------------------- # Installation preparation # # These should be set before any MITK install macros are used #----------------------------------------------------------------------------- # on Mac OSX all BlueBerry plugins get copied into every # application bundle (.app directory) specified here if(MITK_USE_BLUEBERRY AND APPLE) include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) list(GET target_info_list 0 app_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name}) endif() endforeach() endif() #----------------------------------------------------------------------------- # Set coverage Flags #----------------------------------------------------------------------------- if(WITH_COVERAGE) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG") set(COVERAGE_CXX_FLAGS ${coverage_flags}) set(COVERAGE_C_FLAGS ${coverage_flags}) endif() endif() #----------------------------------------------------------------------------- # MITK C/CXX Flags #----------------------------------------------------------------------------- set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}") set(MITK_C_FLAGS_DEBUG ) set(MITK_C_FLAGS_RELEASE ) set(MITK_CXX_FLAGS "${COVERAGE_CXX_FLAGS} ${MITK_CXX14_FLAG}") set(MITK_CXX_FLAGS_DEBUG ) set(MITK_CXX_FLAGS_RELEASE ) set(MITK_EXE_LINKER_FLAGS ) set(MITK_SHARED_LINKER_FLAGS ) find_package(OpenMP) if (OPENMP_FOUND) set(MITK_C_FLAGS "${MITK_C_FLAGS} ${OpenMP_C_FLAGS}") set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") endif() if(WIN32) set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN -DNOMINMAX") mitkFunctionCheckCompilerFlags("/wd4005" MITK_CXX_FLAGS) # warning C4005: macro redefinition mitkFunctionCheckCompilerFlags("/wd4231" MITK_CXX_FLAGS) # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation # the following line should be removed after fixing bug 17637 mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap mitkFunctionCheckCompilerFlags("/wd4180" MITK_CXX_FLAGS) # warning C4180: qualifier applied to function type has no meaning endif() if(NOT MSVC_VERSION) foreach(_flag -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Wno-error=gnu -Wno-error=unknown-pragmas # The strict-overflow warning is generated by ITK template code -Wno-error=strict-overflow -Woverloaded-virtual -Wstrict-null-sentinel #-Wold-style-cast #-Wsign-promo -Wno-array-bounds -fdiagnostics-show-option ) mitkFunctionCheckCAndCXXCompilerFlags(${_flag} MITK_C_FLAGS MITK_CXX_FLAGS) endforeach() endif() if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE) mitkFunctionCheckCompilerFlags("-Wl,--no-undefined" MITK_SHARED_LINKER_FLAGS) mitkFunctionCheckCompilerFlags("-Wl,--as-needed" MITK_SHARED_LINKER_FLAGS) endif() if(CMAKE_COMPILER_IS_GNUCXX) mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS) if(MINGW) # suppress warnings about auto imported symbols set(MITK_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import ${MITK_SHARED_LINKER_FLAGS}") endif() set(MITK_CXX_FLAGS_RELEASE "-U_FORTIFY_SOURCES -D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}") endif() set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS}) #----------------------------------------------------------------------------- # MITK Packages #----------------------------------------------------------------------------- set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends) set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR}) +foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + set(MITK_PACKAGE_DEPENDS_EXTENSION_DIR ${MITK_EXTENSION_DIR}/CMake/PackageDepends) + get_filename_component(MITK_PACKAGE_DEPENDS_EXTENSION_DIR ${MITK_PACKAGE_DEPENDS_EXTENSION_DIR} ABSOLUTE) + if(EXISTS ${MITK_PACKAGE_DEPENDS_EXTENSION_DIR}) + list(APPEND MODULES_PACKAGE_DEPENDS_DIRS ${MITK_PACKAGE_DEPENDS_EXTENSION_DIR}) + endif() +endforeach() + if(NOT MITK_USE_SYSTEM_Boost) set(Boost_NO_SYSTEM_PATHS 1) endif() set(Boost_USE_MULTITHREADED 1) set(Boost_USE_STATIC_LIBS 0) set(Boost_USE_STATIC_RUNTIME 0) set(Boost_ADDITIONAL_VERSIONS "1.65" "1.65.1") # We need this later for a DCMTK workaround set(_dcmtk_dir_orig ${DCMTK_DIR}) # This property is populated at the top half of this file get_property(MITK_EXTERNAL_PROJECTS GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(MITK_USE_${ep} AND _package) if(_components) find_package(${_package} COMPONENTS ${_components} REQUIRED CONFIG) else() # Prefer config mode first because it finds external # Config.cmake files pointed at by _DIR variables. # Otherwise, existing Find.cmake files could fail. find_package(${_package} QUIET CONFIG) string(TOUPPER "${_package}" _package_uc) if(NOT (${_package}_FOUND OR ${_package_uc}_FOUND)) find_package(${_package} REQUIRED) endif() endif() endif() endforeach() # Ensure that the MITK CMake module path comes first set(CMAKE_MODULE_PATH ${MITK_CMAKE_DIR} ${CMAKE_MODULE_PATH} ) if(MITK_USE_DCMTK) # Due to the preferred CONFIG mode in find_package calls above, # the DCMTKConfig.cmake file is read, which does not provide useful # package information. We explictly need MODULE mode to find DCMTK. if(${_dcmtk_dir_orig} MATCHES "${MITK_EXTERNAL_PROJECT_PREFIX}.*") # Help our FindDCMTK.cmake script find our super-build DCMTK set(DCMTK_DIR ${MITK_EXTERNAL_PROJECT_PREFIX}) else() # Use the original value set(DCMTK_DIR ${_dcmtk_dir_orig}) endif() find_package(DCMTK REQUIRED MODULE) endif() if(MITK_USE_DCMQI) # Due to the preferred CONFIG mode in find_package calls above, # the DCMQIConfig.cmake file is read, which does not provide useful # package information. We explictly need MODULE mode to find DCMQI. # Help our FindDCMQI.cmake script find our super-build DCMQI set(DCMQI_DIR ${MITK_EXTERNAL_PROJECT_PREFIX}) find_package(DCMQI REQUIRED) endif() if(MITK_USE_Python) find_package(PythonLibs REQUIRED) find_package(PythonInterp REQUIRED) if(MITK_USE_Numpy) find_package(Numpy REQUIRED) endif() endif() link_directories(${Boost_LIBRARY_DIRS}) if(MITK_USE_OpenIGTLink) link_directories(${OpenIGTLink_LIBRARY_DIRS}) endif() if(MITK_USE_SimpleITK) link_directories(${SimpleITK_LIBRARY_DIRS}) endif() if(MITK_USE_OpenCL) find_package(OpenCL REQUIRED) endif() # Qt support if(MITK_USE_Qt5) find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) # at least Core required get_target_property(_qmake_exec Qt5::qmake LOCATION) execute_process(COMMAND ${_qmake_exec} -query QT_INSTALL_BINS RESULT_VARIABLE _result OUTPUT_VARIABLE QT_BINARY_DIR ERROR_VARIABLE _error ) string(STRIP "${QT_BINARY_DIR}" QT_BINARY_DIR) if(_result OR NOT EXISTS "${QT_BINARY_DIR}") message(FATAL_ERROR "Could not determine Qt binary directory: ${_result} ${QT_BINARY_DIR} ${_error}") endif() find_program(QT_HELPGENERATOR_EXECUTABLE NAMES qhelpgenerator qhelpgenerator-qt5 qhelpgenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_COLLECTIONGENERATOR_EXECUTABLE NAMES qcollectiongenerator qcollectiongenerator-qt5 qcollectiongenerator5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_ASSISTANT_EXECUTABLE NAMES assistant assistant-qt5 assistant5 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) find_program(QT_XMLPATTERNS_EXECUTABLE NAMES xmlpatterns PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH ) mark_as_advanced(QT_HELPGENERATOR_EXECUTABLE QT_COLLECTIONGENERATOR_EXECUTABLE QT_ASSISTANT_EXECUTABLE QT_XMLPATTERNS_EXECUTABLE ) if(MITK_USE_BLUEBERRY) option(BLUEBERRY_USE_QT_HELP "Enable support for integrating plugin documentation into Qt Help" ${DOXYGEN_FOUND}) mark_as_advanced(BLUEBERRY_USE_QT_HELP) # Sanity checks for in-application BlueBerry plug-in help generation if(BLUEBERRY_USE_QT_HELP) set(_force_blueberry_use_qt_help_to_off 0) if(NOT DOXYGEN_FOUND) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen was not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(DOXYGEN_FOUND AND DOXYGEN_VERSION VERSION_LESS 1.8.7) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen version 1.8.7 or newer not found.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_HELPGENERATOR_EXECUTABLE) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because QT_HELPGENERATOR_EXECUTABLE is empty.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT MITK_USE_Qt5_WebEngine) message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because MITK_USE_Qt5_WebEngine is OFF.") set(_force_blueberry_use_qt_help_to_off 1) endif() if(NOT QT_XMLPATTERNS_EXECUTABLE) message("You have enabled Qt Help support, but QT_XMLPATTERNS_EXECUTABLE is empty") set(_force_blueberry_use_qt_help_to_off 1) endif() if(_force_blueberry_use_qt_help_to_off) set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating plugin documentation into Qt Help" FORCE) endif() endif() if(BLUEBERRY_QT_HELP_REQUIRED AND NOT BLUEBERRY_USE_QT_HELP) message(FATAL_ERROR "BLUEBERRY_USE_QT_HELP is required to be set to ON") endif() endif() endif() #----------------------------------------------------------------------------- # Testing #----------------------------------------------------------------------------- if(BUILD_TESTING) enable_testing() include(CTest) mark_as_advanced(TCL_TCLSH DART_ROOT) option(MITK_ENABLE_RENDERING_TESTING OFF "Enable the MITK rendering tests. Requires x-server in Linux.") #Rendering testing does not work for Linux nightlies, thus it is disabled per default #and activated for Mac and Windows. if(WIN32 OR APPLE) set(MITK_ENABLE_RENDERING_TESTING ON) endif() mark_as_advanced( MITK_ENABLE_RENDERING_TESTING ) # Setup file for setting custom ctest vars configure_file( CMake/CTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @ONLY ) # Initial cache for ProjectTemplate and PluginGenerator tests configure_file( CMake/mitkTestInitialCache.txt.in ${MITK_BINARY_DIR}/mitkTestInitialCache.txt @ONLY ) # Configuration for the CMake-generated test driver set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include ") set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN " try {") set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " } catch( std::exception & excp ) { fprintf(stderr,\"%s\\n\",excp.what()); return EXIT_FAILURE; } catch( ... ) { printf(\"Exception caught in the test driver\\n\"); return EXIT_FAILURE; } ") set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output") if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR}) file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR}) endif() # Test the external project template if(MITK_USE_BLUEBERRY) include(mitkTestProjectTemplate) endif() # Test the package target include(mitkPackageTest) endif() configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h) #----------------------------------------------------------------------------- # MITK_SUPERBUILD_BINARY_DIR #----------------------------------------------------------------------------- # If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild. # In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR) set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR}) endif() #----------------------------------------------------------------------------- # Set C/CXX and linker flags for MITK code #----------------------------------------------------------------------------- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}") #----------------------------------------------------------------------------- # Add custom targets representing CDash subprojects #----------------------------------------------------------------------------- foreach(subproject ${CTEST_PROJECT_SUBPROJECTS}) if(NOT TARGET ${subproject} AND NOT subproject MATCHES "Unlabeled") add_custom_target(${subproject}) endif() endforeach() #----------------------------------------------------------------------------- # Add subdirectories #----------------------------------------------------------------------------- add_subdirectory(Utilities) add_subdirectory(Modules) +include("${CMAKE_CURRENT_SOURCE_DIR}/Modules/ModuleList.cmake") +mitkFunctionWhitelistModules(MITK MITK_MODULES) + +foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + set(MITK_MODULES_EXTENSION_DIR ${MITK_EXTENSION_DIR}/Modules) + get_filename_component(MITK_MODULES_EXTENSION_DIR ${MITK_MODULES_EXTENSION_DIR} ABSOLUTE) + if(EXISTS ${MITK_MODULES_EXTENSION_DIR}/ModuleList.cmake) + set(MITK_MODULES "") + include(${MITK_MODULES_EXTENSION_DIR}/ModuleList.cmake) + foreach(mitk_module ${MITK_MODULES}) + add_subdirectory(${MITK_MODULES_EXTENSION_DIR}/${mitk_module} Modules/${mitk_module}) + endforeach() + endif() +endforeach() + if(MITK_USE_BLUEBERRY) set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/) - set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins) - # Plug-in testing (needs some work to be enabled again) if(BUILD_TESTING) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp") if(TARGET CoreApp) get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE) if(APPLE AND _is_macosx_bundle) set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp") endif() endif() set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake") mitkFunctionWhitelistPlugins(MITK MITK_PLUGINS) set(mitk_plugins_fullpath "") foreach(mitk_plugin ${MITK_PLUGINS}) list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin}) endforeach() + foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + set(MITK_PLUGINS_EXTENSION_DIR ${MITK_EXTENSION_DIR}/Plugins) + get_filename_component(MITK_PLUGINS_EXTENSION_DIR ${MITK_PLUGINS_EXTENSION_DIR} ABSOLUTE) + if(EXISTS ${MITK_PLUGINS_EXTENSION_DIR}/PluginList.cmake) + set(MITK_PLUGINS "") + include(${MITK_PLUGINS_EXTENSION_DIR}/PluginList.cmake) + foreach(mitk_plugin ${MITK_PLUGINS}) + list(APPEND mitk_plugins_fullpath ${MITK_PLUGINS_EXTENSION_DIR}/${mitk_plugin}) + endforeach() + endif() + endforeach() + if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake) include(${MITK_PRIVATE_MODULES}/PluginList.cmake) foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS}) list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin}) endforeach() endif() if(MITK_BUILD_EXAMPLES) include("${CMAKE_CURRENT_SOURCE_DIR}/Examples/Plugins/PluginList.cmake") set(mitk_example_plugins_fullpath ) foreach(mitk_example_plugin ${MITK_EXAMPLE_PLUGINS}) list(APPEND mitk_example_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) list(APPEND mitk_plugins_fullpath Examples/Plugins/${mitk_example_plugin}) endforeach() endif() # Specify which plug-ins belong to this project macro(GetMyTargetLibraries all_target_libraries varname) set(re_ctkplugin_mitk "^org_mitk_[a-zA-Z0-9_]+$") set(re_ctkplugin_bb "^org_blueberry_[a-zA-Z0-9_]+$") set(_tmp_list) list(APPEND _tmp_list ${all_target_libraries}) ctkMacroListFilter(_tmp_list re_ctkplugin_mitk re_ctkplugin_bb OUTPUT_VARIABLE ${varname}) endmacro() # Get infos about application directories and build options include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake") set(mitk_apps_fullpath ) foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 directory_name) list(GET target_info_list 1 option_name) if(${option_name}) list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${directory_name}^^${option_name}") endif() endforeach() if (mitk_plugins_fullpath) ctkMacroSetupPlugins(${mitk_plugins_fullpath} BUILD_OPTION_PREFIX MITK_BUILD_ APPS ${mitk_apps_fullpath} BUILD_ALL ${MITK_BUILD_ALL_PLUGINS} COMPACT_OPTIONS) endif() set(MITK_PLUGIN_USE_FILE "${MITK_BINARY_DIR}/MitkPluginUseFile.cmake") if(${PROJECT_NAME}_PLUGIN_LIBRARIES) ctkFunctionGeneratePluginUseFile(${MITK_PLUGIN_USE_FILE}) else() file(REMOVE ${MITK_PLUGIN_USE_FILE}) set(MITK_PLUGIN_USE_FILE ) endif() endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- if(DOXYGEN_FOUND) add_subdirectory(Documentation) endif() #----------------------------------------------------------------------------- # Installation #----------------------------------------------------------------------------- # set MITK cpack variables # These are the default variables, which can be overwritten ( see below ) include(mitkSetupCPack) set(use_default_config ON) # MITK_APPS is set in Applications/AppList.cmake (included somewhere above # if MITK_USE_BLUEBERRY is set to ON). if(MITK_APPS) set(activated_apps_no 0) list(LENGTH MITK_APPS app_count) # Check how many apps have been enabled # If more than one app has been activated, the we use the # default CPack configuration. Otherwise that apps configuration # will be used, if present. foreach(mitk_app ${MITK_APPS}) # extract option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 1 option_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) MATH(EXPR activated_apps_no "${activated_apps_no} + 1") endif() endforeach() if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS)) # Corner case if there is only one app in total set(use_project_cpack ON) elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS) # Only one app is enabled (no "build all" flag set) set(use_project_cpack ON) else() # Less or more then one app is enabled set(use_project_cpack OFF) endif() foreach(mitk_app ${MITK_APPS}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${mitk_app}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) list(GET target_info_list 2 executable_name) # check if the application is enabled if(${option_name} OR MITK_BUILD_ALL_APPS) # check whether application specific configuration files will be used if(use_project_cpack) # use files if they exist if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake") endif() if(EXISTS "${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in") set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/Applications/${target_dir}/CPackConfig.cmake") configure_file(${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in ${CPACK_PROJECT_CONFIG_FILE} @ONLY) set(use_default_config OFF) endif() endif() # add link to the list list(APPEND CPACK_CREATE_DESKTOP_LINKS "${executable_name}") endif() endforeach() endif() # if no application specific configuration file was used, use default if(use_default_config) configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in ${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY) set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake") endif() # include CPack model once all variables are set include(CPack) # Additional installation rules include(mitkInstallRules) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- # ---------------- Export targets ----------------- set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake") file(REMOVE ${MITK_EXPORTS_FILE}) set(targets_to_export) get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS) if(module_targets) list(APPEND targets_to_export ${module_targets}) endif() if(MITK_USE_BLUEBERRY) if(MITK_PLUGIN_LIBRARIES) list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES}) endif() endif() export(TARGETS ${targets_to_export} APPEND FILE ${MITK_EXPORTS_FILE}) set(MITK_EXPORTED_TARGET_PROPERTIES ) foreach(target_to_export ${targets_to_export}) get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS) if(autoload_targets) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")") endif() get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY) if(autoload_dir) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")") endif() get_target_property(deprecated_module ${target_to_export} MITK_MODULE_DEPRECATED_SINCE) if(deprecated_module) set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES} set_target_properties(${target_to_export} PROPERTIES MITK_MODULE_DEPRECATED_SINCE \"${deprecated_module}\")") endif() endforeach() # ---------------- External projects ----------------- get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) set(MITK_CONFIG_EXTERNAL_PROJECTS ) #string(REPLACE "^^" ";" _mitk_external_projects ${MITK_EXTERNAL_PROJECTS}) foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} set(MITK_USE_${ep} ${MITK_USE_${ep}}) set(MITK_${ep}_DIR \"${${ep}_DIR}\") set(MITK_${ep}_COMPONENTS ${_components}) ") endforeach() foreach(ep ${MITK_EXTERNAL_PROJECTS}) get_property(_package GLOBAL PROPERTY MITK_${ep}_PACKAGE) get_property(_components GLOBAL PROPERTY MITK_${ep}_COMPONENTS) if(_components) set(_components_arg COMPONENTS \${_components}) else() set(_components_arg) endif() if(_package) set(MITK_CONFIG_EXTERNAL_PROJECTS "${MITK_CONFIG_EXTERNAL_PROJECTS} if(MITK_USE_${ep}) set(${ep}_DIR \${MITK_${ep}_DIR}) if(MITK_${ep}_COMPONENTS) mitkMacroFindDependency(${_package} COMPONENTS \${MITK_${ep}_COMPONENTS}) else() mitkMacroFindDependency(${_package}) endif() endif()") endif() endforeach() # ---------------- Tools ----------------- configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in ${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY) configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in ${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY) # ---------------- Configure files ----------------- configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc) set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities) configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h) configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY) write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion) #----------------------------------------------------------------------------- # MITK Applications #----------------------------------------------------------------------------- # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Applications) #----------------------------------------------------------------------------- # MITK Examples #----------------------------------------------------------------------------- if(MITK_BUILD_EXAMPLES) # This must come after MITKConfig.h was generated, since applications # might do a find_package(MITK REQUIRED). add_subdirectory(Examples) endif() #----------------------------------------------------------------------------- # Print configuration summary #----------------------------------------------------------------------------- message("\n\n") feature_summary( DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------" WHAT ALL ) - diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 56566ba8c6..b6f9fe8226 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -1,37 +1,28 @@ #----------------------------------------------------------------------------- # Configure the CppMicroServices build #----------------------------------------------------------------------------- set(CppMicroServices_DIR_default "${CMAKE_CURRENT_BINARY_DIR}/CppMicroServices") if(NOT CppMicroServices_DIR) set(CppMicroServices_DIR ${CppMicroServices_DIR_default} CACHE PATH "Path to the CppMicroServices library" FORCE) endif() mark_as_advanced(CppMicroServices_DIR) if ("${CppMicroServices_DIR}" STREQUAL "${CppMicroServices_DIR_default}") set(US_ENABLE_AUTOLOADING_SUPPORT ON) set(US_ENABLE_THREADING_SUPPORT ON) # Don't create a "doc" target and don't install the documentation files set(US_NO_DOCUMENTATION ON) # Don't install anything for now (we use the CMake BundleUtilities script) set(US_NO_INSTALL 1) if(BUILD_TESTING) set(US_BUILD_TESTING ON) endif() mitkFunctionCheckCompilerFlags("-std=c++14" US_CXX_FLAGS) add_subdirectory(CppMicroServices) endif() - -#----------------------------------------------------------------------------- -# Configure standard MITK modules -#----------------------------------------------------------------------------- - -set(MITK_DEFAULT_SUBPROJECTS MITK-Modules) - -include(ModuleList.cmake) -mitkFunctionWhitelistModules(MITK mitk_modules) diff --git a/Modules/CppMicroServices/tools/usResourceCompiler.c b/Modules/CppMicroServices/tools/usResourceCompiler.c index 22970f37f2..05a5a3743a 100644 --- a/Modules/CppMicroServices/tools/usResourceCompiler.c +++ b/Modules/CppMicroServices/tools/usResourceCompiler.c @@ -1,663 +1,663 @@ /*============================================================================= Library: CppMicroServices Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #include "miniz.h" #include #include #include #include #define US_STR_(x) #x #define US_STR(x) US_STR_(x) static int cleanup_archive(mz_zip_archive* writeArchive) { if (writeArchive && writeArchive->m_zip_mode != MZ_ZIP_MODE_INVALID) { if (writeArchive->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED) { if (!mz_zip_writer_finalize_archive(writeArchive)) { return -1; } } if (writeArchive->m_zip_mode != MZ_ZIP_MODE_INVALID) { if (!mz_zip_writer_end(writeArchive)) { return -1; } } } return 0; } static void exit_printf(mz_zip_archive* writeArchive, const char* format, ...) { va_list args; cleanup_archive(writeArchive); fprintf(stderr, "error: "); va_start(args, format); vfprintf(stderr, format, args); va_end(args); exit(EXIT_FAILURE); } static void exit_perror(mz_zip_archive* writeArchive, const char* desc) { cleanup_archive(writeArchive); fprintf(stderr, "error: "); perror(desc); exit(EXIT_FAILURE); } // --------------------------------------------------------------------------------- // -------------------------- PLATFORM SPECIFIC CODE ------------------------- // --------------------------------------------------------------------------------- #if defined(_WIN32) || defined(_WIN64) #define WIN32_LEAN_AND_MEAN #define VC_EXTRALEAN #include #include #include #include #include #include static char* get_error_str() { // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); return lpMsgBuf; } static void free_error_str(char* buf) { LocalFree(buf); } static char* us_strcpy(char* dest, size_t dest_size, const char* src) { if (strcpy_s(dest, dest_size, src)) { char* err_str = get_error_str(); exit_printf(NULL, NULL, err_str); } return dest; } static char* us_strncpy(char* dest, size_t dest_size, const char* src, size_t count) { if (strncpy_s(dest, dest_size, src, count)) { char* err_str = get_error_str(); exit_printf(NULL, NULL, err_str); } return dest; } static FILE* us_fopen(const char* filename, const char* mode) { FILE* file = NULL; fopen_s(&file, filename, mode); return file; } #define US_CWD(b, s) _getcwd(b, s) #define US_CLOSE _close #define US_READ _read #define US_FOPEN us_fopen #define US_FILENO _fileno #define US_STRCASECMP _stricmp #define US_STRCPY us_strcpy #define US_STRNCPY us_strncpy #define US_SSCANF sscanf_s #else #include static char* get_error_str() { return strerror(errno); } static void free_error_str(char* buf) { } static char* us_strcpy(char* dest, size_t dest_size, const char* src) { return strcpy(dest, src); } static char* us_strncpy(char* dest, size_t dest_size, const char* src, size_t count) { return strncpy(dest, src, count); } #define US_CLOSE close #define US_READ read #define US_FOPEN fopen #define US_FILENO fileno #define US_STRCASECMP strcasecmp #define US_STRCPY us_strcpy #define US_STRNCPY us_strncpy #define US_SSCANF sscanf #endif // --------------------------------------------------------------------------------- // ----------------------------- DEBUGGING STUFF ----------------------------- // --------------------------------------------------------------------------------- //#define DEBUG_TRACE #ifdef DEBUG_TRACE #define dbg_print printf #else static int void_printf(const char* format, ...) { return 0; } #define dbg_print void_printf #endif // --------------------------------------------------------------------------------- // ----------------------------- HELPER FUNCTIONS ---------------------------- // --------------------------------------------------------------------------------- void* malloc_or_abort(size_t size) { void* p; if (size == 0) size = 1; p = malloc(size); if (!p) { // try to print an error message; this might very well fail - fprintf(stderr, "Could not allocate enough memory (%ld bytes)\n", size); + fprintf(stderr, "Could not allocate enough memory (%lld bytes)\n", size); abort(); } return p; } static int cmpzipindex(const void *i1, const void *i2) { mz_uint index1 = *(const mz_uint*)i1; mz_uint index2 = *(const mz_uint*)i2; return index1 == index2 ? 0 : (index1 < index2 ? -1 : 1); } static int cmpstringp(const void *p1, const void *p2) { return US_STRCASECMP(* (char * const *) p1, * (char * const *) p2); } typedef struct us_archived_names_tag { char** names; mz_uint size; mz_uint capacity; mz_uint orderedSize; } us_archived_names; static void us_archived_names_free(us_archived_names * archivedNames) { mz_uint i; for (i = 0; i < archivedNames->size; ++i) { free(archivedNames->names[i]); } free(archivedNames->names); } enum { US_OK = 0, US_ARCHIVED_NAMES_ERROR_DUPLICATE = 1, US_MZ_ERROR_ADD_FILE = 2, US_ERROR_INVALID = 3 }; // messages can take two arguments: // 1. The archive entry name // 2. The path of the zip archive const char* us_error_msg[] = { "ok\n", "Duplicate entry '%s' (in %s)\n", "Could not add resource %s\n" }; static int us_archived_names_append(us_archived_names* archivedNames, const char* archiveName) { if (archivedNames->names != NULL && bsearch(&archiveName, archivedNames->names, archivedNames->orderedSize, sizeof(char*), cmpstringp) != NULL) { return US_ARCHIVED_NAMES_ERROR_DUPLICATE; } if (archivedNames->size >= archivedNames->capacity) { size_t newCapacity = archivedNames->size > archivedNames->capacity + 100 ? archivedNames->size + 1 : archivedNames->capacity + 100; archivedNames->names = realloc(archivedNames->names, newCapacity * sizeof(char*)); if (archivedNames->names == NULL) { - fprintf(stderr, "Could not realloc enough memory (%ld bytes)\n", newCapacity); + fprintf(stderr, "Could not realloc enough memory (%lld bytes)\n", newCapacity); abort(); } memset(archivedNames->names + archivedNames->capacity, 0, sizeof(char*) * (newCapacity - archivedNames->capacity)); archivedNames->capacity = (mz_uint)newCapacity; } if (archivedNames->names[archivedNames->size] == NULL) { archivedNames->names[archivedNames->size] = malloc_or_abort(MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE * sizeof(char)); } US_STRCPY(archivedNames->names[archivedNames->size], MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE, archiveName); ++archivedNames->size; return US_OK; } static void us_archived_names_sort(us_archived_names* archivedNames) { qsort(archivedNames->names, archivedNames->size, sizeof(char*), cmpstringp); archivedNames->orderedSize = archivedNames->size; } static int us_zip_writer_add_dir_entries(mz_zip_archive* pZip, const char* pArchive_name, us_archived_names* archived_dirs) { size_t end; size_t length = strlen(pArchive_name); char dirName[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; if (sizeof dirName < length - 1) { // This should be impossible - fprintf(stderr, "Archive file name '%s' too long (%ld > %ld)", pArchive_name, length-1, sizeof dirName); + fprintf(stderr, "Archive file name '%s' too long (%lld > %lld)", pArchive_name, length-1, sizeof dirName); exit(EXIT_FAILURE); } // split the archive name into directory tokens for (end = 0; end < length; ++end) { if (pArchive_name[end] == '/') { US_STRNCPY(dirName, sizeof dirName, pArchive_name, end + 1); //if (end < length-1) //{ dirName[end+1] = '\0'; //} if (us_archived_names_append(archived_dirs, dirName) == US_OK) { dbg_print("-- found new dir entry %s\n", dirName); // The directory entry does not yet exist, so add it if (!mz_zip_writer_add_mem(pZip, dirName, NULL, 0, MZ_NO_COMPRESSION)) { dbg_print("-- zip add_mem error\n"); return US_MZ_ERROR_ADD_FILE; } us_archived_names_sort(archived_dirs); } } } return US_OK; } static int us_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, us_archived_names* archived_names, us_archived_names* archived_dirs) { int retCode = us_archived_names_append(archived_names, pArchive_name); if (US_OK != retCode) return retCode; if (!mz_zip_writer_add_file(pZip, pArchive_name, pSrc_filename, pComment, comment_size, level_and_flags)) { return US_MZ_ERROR_ADD_FILE; } return us_zip_writer_add_dir_entries(pZip, pArchive_name, archived_dirs); } static int us_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index, us_archived_names* archived_names, us_archived_names* archived_dirs, char* archiveName, mz_uint archiveNameSize) { int retCode = 0; mz_uint numBytes = mz_zip_reader_get_filename(pSource_zip, file_index, archiveName, archiveNameSize); if (numBytes > 1 && archiveName[numBytes-2] != '/') { retCode = us_archived_names_append(archived_names, archiveName); if (US_OK != retCode) return retCode; if (!mz_zip_writer_add_from_zip_reader(pZip, pSource_zip, file_index)) { return US_MZ_ERROR_ADD_FILE; } } return us_zip_writer_add_dir_entries(pZip, archiveName, archived_dirs); } // --------------------------------------------------------------------------------- // ----------------------------- MAIN ENTRY POINT ---------------------------- // --------------------------------------------------------------------------------- int main(int argc, char** argv) { int compressionLevel = 6; int argIndex = 0; int bPrintHelp = 0; int bAppendMode = 0; int errCode = US_OK; int mergeFlag = 0; const char* zipFile = NULL; const char* moduleName = NULL; size_t moduleNameLength = 0; FILE* zipfileStream = NULL; mz_zip_archive writeArchive; us_archived_names archivedNames; us_archived_names archivedDirs; FILE* appendStream = NULL; char archiveName[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; int numZipArgs = 0; int* zipArgIndices = NULL; mz_zip_archive currFileArchive; int zipArgIndex = 0; char readBuffer[1024]; mz_uint numRead = 0; // --------------------------------------------------------------------------------- // COMMAND LINE VALIDATION // --------------------------------------------------------------------------------- if (argc < 4) { bPrintHelp = 1; } else if (argv[1][0] == '-') { if (strlen(argv[1]) == 2) { if (US_SSCANF(argv[1], "-%1d", &compressionLevel) != 1) { bPrintHelp = 1; } else { argIndex = 1; if (argc < 5 || compressionLevel < 0 || compressionLevel > 9) bPrintHelp = 1; } } else if (strcmp(argv[1], "--append") == 0) { if (argc > 4) { bPrintHelp = 1; } bAppendMode = 1; } else { bPrintHelp = 1; } } if (bPrintHelp) { printf("A resource compiler for C++ Micro Services modules\n\n"); printf("Usage: usResourceCompiler [-#] zipfile modulename [[-a] file...] [-m archive...]\n"); printf("Usage: usResourceCompiler --append outfile zipfile\n\n"); printf("Add entries to zipfile and merge archives.\n\n"); printf(" -# (-0, -1, -2, -3, -4, -5, -6, -7, -8, -9)\n"); printf(" The Zip compression level. The default compression level is -6.\n"); printf(" zipfile The absolute path of the zip file.\n"); printf(" modulename The module name as specified in the MODULE_NAME compile definition.\n"); printf(" file Path to a resource file, relative to the current working directory.\n"); printf(" archive Path to a zip archive for merging into zipfile.\n"); exit(EXIT_SUCCESS); } if (bAppendMode) { // Special "append" mode. Just append zipfile to outfile as a binary blob. // Open the module file for appending the temporary zip archive dbg_print("Opening outfile '%s' as ab... ", argv[2]); if (NULL == (appendStream = US_FOPEN(argv[2], "ab"))) { dbg_print("failure\n"); exit_perror(NULL, "fopen"); } else { dbg_print("success\n"); } dbg_print("Opening zipfile '%s' as rb... ", argv[3]); if (NULL == (zipfileStream = US_FOPEN(argv[3], "rb"))) { dbg_print("failure\n"); exit_perror(NULL, "fopen"); } else { dbg_print("success\n"); } dbg_print("Appending zipfile to outfile\n"); do { numRead = US_READ(US_FILENO(zipfileStream), readBuffer, sizeof(readBuffer)); if (numRead == -1) { exit_perror(NULL, "read"); } fwrite(readBuffer, numRead, 1, appendStream); if (ferror(appendStream)) { exit_printf(&writeArchive, "Appending zipfile failed\n"); } } while (numRead != 0); fclose(zipfileStream); fclose(appendStream); exit(EXIT_SUCCESS); } // --------------------------------------------------------------------------------- // OPEN OR CREATE ZIP FILE // --------------------------------------------------------------------------------- zipFile = argv[++argIndex]; moduleName = argv[++argIndex]; moduleNameLength = strlen(moduleName); memset(&writeArchive, 0, sizeof(writeArchive)); memset(&archivedNames, 0, sizeof archivedNames); memset(&archivedDirs, 0, sizeof archivedDirs); // --------------------------------------------------------------------------------- // ZIP ARCHIVE WRITING (temporary archive) // --------------------------------------------------------------------------------- // Create a new zip archive which will be copied to zipfile later dbg_print("Creating zip archive\n"); remove(zipFile); if (!mz_zip_writer_init_file(&writeArchive, zipFile, 0)) { exit_printf(&writeArchive, "Internal error, could not init new zip archive\n"); } dbg_print("Initialized zip archive\n"); // Add current files to the zip archive zipArgIndices = malloc_or_abort(argc * sizeof *zipArgIndices); while(++argIndex < argc) { const char* fileName = argv[argIndex]; const size_t fileNameLength = strlen(fileName); // determine the argument type if (strcmp(argv[argIndex], "-a") == 0) { mergeFlag = 0; continue; } else if (strcmp(argv[argIndex], "-m") == 0) { mergeFlag = 1; continue; } if (mergeFlag) { // check if the current file is a valid zip archive memset(&currFileArchive, 0, sizeof(currFileArchive)); if (mz_zip_reader_init_file(&currFileArchive, fileName, 0)) { dbg_print("Input is a valid zip archive: %s\n", fileName); zipArgIndices[numZipArgs++] = argIndex; mz_zip_reader_end(&currFileArchive); } // silently ignore files which are not zip archives continue; } if (fileNameLength + 1 + moduleNameLength > MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1) { exit_printf(&writeArchive, "Resource filename too long: %s\n", moduleName); } US_STRCPY(archiveName, sizeof archiveName, moduleName); archiveName[moduleNameLength] = '/'; US_STRCPY(archiveName + moduleNameLength + 1, (sizeof archiveName) - (moduleNameLength + 1), fileName); printf(" adding: %s\n", archiveName); // add the current file to the new archive if ((errCode = us_zip_writer_add_file(&writeArchive, archiveName, fileName, NULL, 0, compressionLevel, &archivedNames, &archivedDirs))) { dbg_print("Adding %s failed\n", archiveName); exit_printf(&writeArchive, us_error_msg[errCode], archiveName, fileName); } } us_archived_names_sort(&archivedNames); dbg_print("Added cmd line files to zip archive\n"); // --------------------------------------------------------------------------------- // MERGE ZIPFILE ENTRIES (into temporary archive) // --------------------------------------------------------------------------------- for (zipArgIndex = 0; zipArgIndex < numZipArgs; ++zipArgIndex) { mz_zip_archive currZipArchive; const char* currArchiveFileName = NULL; mz_uint currZipIndex = 0; mz_uint numZipIndices = 0; memset(&currZipArchive, 0, sizeof(mz_zip_archive)); currArchiveFileName = argv[zipArgIndices[zipArgIndex]]; if (!mz_zip_reader_init_file(&currZipArchive, currArchiveFileName, 0)) { exit_printf(&writeArchive, "Could not initialize zip archive %s\n", currArchiveFileName); } numZipIndices = mz_zip_reader_get_num_files(&currZipArchive); for (currZipIndex = 0; currZipIndex < numZipIndices; ++currZipIndex) { errCode = us_zip_writer_add_from_zip_reader(&writeArchive, &currZipArchive, currZipIndex, &archivedNames, &archivedDirs, archiveName, sizeof archiveName); printf(" merging: %s (from %s)\n", archiveName, currArchiveFileName); if (errCode == US_ARCHIVED_NAMES_ERROR_DUPLICATE) { printf(" warning: Merge failed: "); printf(us_error_msg[errCode], archiveName, currArchiveFileName); } else if (errCode != US_OK) { mz_zip_reader_end(&currZipArchive); exit_printf(&writeArchive, us_error_msg[errCode], archiveName, currArchiveFileName); } } mz_zip_reader_end(&currZipArchive); us_archived_names_sort(&archivedNames); } // We are finished, finalize the zip archive if (!mz_zip_writer_finalize_archive(&writeArchive)) { exit_printf(&writeArchive, "Could not finalize zip archive\n"); } dbg_print("Finalized zip archive\n"); // --------------------------------------------------------------------------------- // CLEANUP // --------------------------------------------------------------------------------- free(zipArgIndices); us_archived_names_free(&archivedNames); us_archived_names_free(&archivedDirs); if (cleanup_archive(&writeArchive) == -1) { fprintf(stderr, "Internal error finalizing zip archive\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } diff --git a/Modules/DataTypesExt/include/mitkMeshUtil.h b/Modules/DataTypesExt/include/mitkMeshUtil.h index 0bfeafbcfa..42024d63e9 100644 --- a/Modules/DataTypesExt/include/mitkMeshUtil.h +++ b/Modules/DataTypesExt/include/mitkMeshUtil.h @@ -1,1681 +1,1681 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKMESHUTIL_H_INCLUDED #define MITKMESHUTIL_H_INCLUDED #if (_MSC_VER == 1200) #error MeshUtils currently not supported for MS Visual C++ 6.0. Sorry. #endif //#include #include #include #include #include #include //#include #include //#include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include template class NullScalarAccessor { public: static inline double GetPointScalar(typename MeshType::PointDataContainer * /*pointData*/, typename MeshType::PointIdentifier /*idx*/, MeshType * /*mesh*/ = nullptr, unsigned int /*type*/ = 0) { return (double)0.0; }; static inline double GetCellScalar(typename MeshType::CellDataContainer * /*cellData*/, typename MeshType::CellIdentifier /*idx*/, MeshType * /*mesh*/ = nullptr, unsigned int /*type*/ = 0) { return (double)0.0; }; }; template class MeshScalarAccessor { public: static inline double GetPointScalar(typename MeshType::PointDataContainer *pointData, typename MeshType::PointIdentifier idx, MeshType * /*mesh*/ = nullptr, unsigned int /*type*/ = 0) { return (double)pointData->GetElement(idx); }; static inline double GetCellScalar(typename MeshType::CellDataContainer *cellData, typename MeshType::CellIdentifier idx, MeshType * /*mesh*/ = nullptr, unsigned int /*type*/ = 0) { return (double)cellData->GetElement(idx); }; }; template class MeanCurvatureAccessor : public NullScalarAccessor { public: static inline double GetPointScalar(typename MeshType::PointDataContainer * /*point*/, typename MeshType::PointIdentifier idx, MeshType *mesh, unsigned int /*type*/ = 0) { typename MeshType::PixelType dis = 0; mesh->GetPointData(idx, &dis); return (double)dis; }; }; template class SimplexMeshAccessor : public NullScalarAccessor { public: static inline double GetPointScalar(typename MeshType::PointDataContainer * /*point*/, typename MeshType::PointIdentifier idx, MeshType *mesh, unsigned int type = 0) { typename MeshType::GeometryMapPointer geometryData = mesh->GetGeometryData(); if (type == 0) { double val = mesh->GetMeanCurvature(idx); mesh->SetPointData(idx, val); return val; } else if (type == 1) { double val = geometryData->GetElement(idx)->meanTension; mesh->SetPointData(idx, val); return val; } else if (type == 2) { double val = geometryData->GetElement(idx)->externalForce.GetNorm(); mesh->SetPointData(idx, val); return val; } else if (type == 3) return geometryData->GetElement(idx)->internalForce.GetNorm(); else if (type == 4) return geometryData->GetElement(idx)->externalForce.GetNorm() * mesh->GetDistance(idx); else if (type == 5) { typename MeshType::PixelType dis = 0; mesh->GetPointData(idx, &dis); return (double)dis; } else if (type == 6) { return (double)((geometryData->GetElement(idx))->allowSplitting); } else return (double)0; }; }; /*! \brief The class provides mehtods for ITK - VTK mesh conversion * * \todo document the inner class * \todo maybe inner class should be moved out */ template > class MeshUtil { /*! \brief A visitor to create VTK cells by means of a class defining the InsertImplementation interface The InsertImplementation interface defines the methods \code void InsertLine(vtkIdType *pts); void InsertTriangle(vtkIdType *pts); void InsertPolygon(vtkIdType npts, vtkIdType *pts); void InsertQuad(vtkIdType *pts); void InsertTetra(vtkIdType *pts); void InsertHexahedron(vtkIdType *pts); \endcode This class calls the appropriate insert-method of the InsertImplementation according to the cell type of the visited cell \em and its actual contents: e.g., for a polygon cell with just two points, a line will be created by calling InsertLine. \sa ExactSwitchByCellType \sa SingleCellArrayInsertImplementation \sa DistributeInsertImplementation */ template class SwitchByCellType : public InsertImplementation { // typedef the itk cells we are interested in typedef typename itk::CellInterface CellInterfaceType; typedef itk::LineCell floatLineCell; typedef itk::TriangleCell floatTriangleCell; typedef itk::PolygonCell floatPolygonCell; typedef itk::QuadrilateralCell floatQuadrilateralCell; typedef itk::TetrahedronCell floatTetrahedronCell; typedef itk::HexahedronCell floatHexahedronCell; typedef typename CellInterfaceType::PointIdConstIterator PointIdIterator; public: /*! Visit a line and create the VTK_LINE cell */ void Visit(unsigned long cellId, floatLineCell *t) { vtkIdType pts[2]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 2) { // useless because itk::LineCell always returns 2 for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a polygon and create the VTK_POLYGON cell */ void Visit(unsigned long cellId, floatPolygonCell *t) { vtkIdType pts[4096]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num > 4096) { MITK_ERROR << "Problem in mitkMeshUtil: Polygon with more than maximum number of vertices encountered." << std::endl; } else if (num > 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertPolygon(num, (vtkIdType *)pts); } else if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle((vtkIdType *)pts); } else if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a triangle and create the VTK_TRIANGLE cell */ void Visit(unsigned long cellId, floatTriangleCell *t) { vtkIdType pts[3]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle((vtkIdType *)pts); } else if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a quad and create the VTK_QUAD cell */ void Visit(unsigned long cellId, floatQuadrilateralCell *t) { vtkIdType pts[4]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 4) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) { if (i == 2) pts[3] = *it; else if (i == 3) pts[2] = *it; else pts[i] = *it; i++; // pts[i++] = *it; } vtkCellId = this->InsertQuad((vtkIdType *)pts); } else if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle((vtkIdType *)pts); } else if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a tetrahedra and create the VTK_TETRA cell */ void Visit(unsigned long cellId, floatTetrahedronCell *t) { vtkIdType pts[4]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 4) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTetra((vtkIdType *)pts); } else if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle((vtkIdType *)pts); } else if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } /*! Visit a hexahedron and create the VTK_HEXAHEDRON cell */ void Visit(unsigned long cellId, floatHexahedronCell *t) { vtkIdType pts[8]; int i = 0; unsigned long num = t->GetNumberOfVertices(); vtkIdType vtkCellId = -1; if (num == 8) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) { if (i == 2) pts[i++] = *(it + 1); else if (i == 3) pts[i++] = *(it - 1); else if (i == 6) pts[i++] = *(it + 1); else if (i == 7) pts[i++] = *(it - 1); else pts[i++] = *it; } vtkCellId = this->InsertHexahedron((vtkIdType *)pts); } else if (num == 4) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertQuad((vtkIdType *)pts); } else if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertTriangle((vtkIdType *)pts); } else if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkCellId = this->InsertLine((vtkIdType *)pts); } if (this->m_UseCellScalarAccessor && vtkCellId >= 0) { this->m_CellScalars->InsertTuple1(vtkCellId, ScalarAccessor::GetCellScalar(this->m_CellData, cellId)); } } }; /*! \brief A visitor similar to SwitchByCellType, but with exact matching of cell types Works as described in SwitchByCellType, but does exact matching of cell types, e.g., for a polygon cell with just two points, \em no insert-method will be called, because a polygon must have at least three points. \sa SwitchByCellType \sa SingleCellArrayInsertImplementation \sa DistributeInsertImplementation */ template class ExactSwitchByCellType : public InsertImplementation { // typedef the itk cells we are interested in typedef typename itk::CellInterface CellInterfaceType; typedef itk::LineCell floatLineCell; typedef itk::TriangleCell floatTriangleCell; typedef itk::PolygonCell floatPolygonCell; typedef itk::QuadrilateralCell floatQuadrilateralCell; typedef itk::TetrahedronCell floatTetrahedronCell; typedef itk::HexahedronCell floatHexahedronCell; typedef typename CellInterfaceType::PointIdConstIterator PointIdIterator; public: /*! Visit a line and create the VTK_LINE cell */ void Visit(unsigned long, floatLineCell *t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType pts[2]; int i = 0; if (num == 2) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; this->InsertLine(pts); } } /*! Visit a polygon and create the VTK_POLYGON cell */ void Visit(unsigned long, floatPolygonCell *t) { vtkIdType pts[4096]; unsigned long num = t->GetNumberOfVertices(); if (num > 4096) { MITK_ERROR << "Problem in mitkMeshUtil: Polygon with more than maximum number of vertices encountered." << std::endl; } int i = 0; if (num > 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; this->InsertPolygon(num, pts); } } /*! Visit a triangle and create the VTK_TRIANGLE cell */ void Visit(unsigned long, floatTriangleCell *t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType pts[3]; int i = 0; if (num == 3) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; this->InsertTriangle(pts); } } /*! Visit a quadrilateral and create the VTK_QUAD cell */ void Visit(unsigned long, floatQuadrilateralCell *t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType pts[4]; int i = 0; if (num == 4) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkIdType tmpId = pts[2]; pts[2] = pts[3]; pts[3] = tmpId; this->InsertQuad(pts); } } /*! Visit a tetrahedron and create the VTK_TETRA cell */ void Visit(unsigned long, floatTetrahedronCell *t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType pts[4]; int i = 0; if (num == 4) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; this->InsertTetra(pts); } } /*! Visit a hexahedron and create the VTK_HEXAHEDRON cell */ void Visit(unsigned long, floatHexahedronCell *t) { unsigned long num = t->GetNumberOfVertices(); vtkIdType pts[8]; int i = 0; if (num == 8) { for (PointIdIterator it = t->PointIdsBegin(); it != t->PointIdsEnd(); it++) pts[i++] = *it; vtkIdType tmp[8]; for (unsigned int i = 0; i < 8; i++) tmp[i] = pts[i]; pts[2] = tmp[3]; pts[3] = tmp[2]; pts[6] = tmp[7]; pts[7] = tmp[6]; this->InsertHexahedron(pts); } } }; /*! \brief Implementation of the InsertImplementation interface of SwitchByCellType to define a visitor that create cells according to their types and put them in a single vtkCellArray (for vtkUnstructuredGrid construction) */ class SingleCellArrayInsertImplementation { vtkCellArray *m_Cells; int *m_TypeArray; // vtkIdType cellId; protected: bool m_UseCellScalarAccessor; vtkFloatArray *m_CellScalars; typename MeshType::CellDataContainer::Pointer m_CellData; public: SingleCellArrayInsertImplementation() : m_UseCellScalarAccessor(false) {} /*! Set the vtkCellArray that will be constructed */ void SetCellArray(vtkCellArray *cells) { m_Cells = cells; } /*! Set the type array for storing the vtk cell types */ void SetTypeArray(int *i) { m_TypeArray = i; } void SetUseCellScalarAccessor(bool flag) { m_UseCellScalarAccessor = flag; } void SetCellScalars(vtkFloatArray *scalars) { m_CellScalars = scalars; } vtkFloatArray *GetCellScalars() { return m_CellScalars; } void SetMeshCellData(typename MeshType::CellDataContainer *data) { m_CellData = data; } vtkIdType InsertLine(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(2, pts); m_TypeArray[cellId] = VTK_LINE; return cellId; } vtkIdType InsertTriangle(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(3, pts); m_TypeArray[cellId] = VTK_TRIANGLE; return cellId; } vtkIdType InsertPolygon(vtkIdType npts, vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(npts, pts); m_TypeArray[cellId] = VTK_POLYGON; return cellId; } vtkIdType InsertQuad(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(4, pts); m_TypeArray[cellId] = VTK_QUAD; return cellId; } vtkIdType InsertTetra(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(4, pts); m_TypeArray[cellId] = VTK_TETRA; return cellId; } vtkIdType InsertHexahedron(vtkIdType *pts) { vtkIdType cellId = m_Cells->InsertNextCell(8, pts); m_TypeArray[cellId] = VTK_HEXAHEDRON; return cellId; } }; /*! \brief Implementation of the InsertImplementation interface of SwitchByCellType to define a visitor that distributes cells according to their types (for vtkPolyData construction) */ class DistributeInsertImplementation { vtkCellArray *m_LineCells; vtkCellArray *m_TriangleCells; vtkCellArray *m_PolygonCells; vtkCellArray *m_QuadCells; protected: bool m_UseCellScalarAccessor; vtkFloatArray *m_CellScalars; typename MeshType::CellDataContainer::Pointer m_CellData; public: DistributeInsertImplementation() : m_UseCellScalarAccessor(false) {} /*! Set the vtkCellArray that will be constructed */ void SetCellArrays(vtkCellArray *lines, vtkCellArray *triangles, vtkCellArray *polygons, vtkCellArray *quads) { m_LineCells = lines; m_TriangleCells = triangles; m_PolygonCells = polygons; m_QuadCells = quads; } vtkIdType InsertLine(vtkIdType *pts) { return m_LineCells->InsertNextCell(2, pts); } vtkIdType InsertTriangle(vtkIdType *pts) { return m_TriangleCells->InsertNextCell(3, pts); } vtkIdType InsertPolygon(vtkIdType npts, vtkIdType *pts) { return m_PolygonCells->InsertNextCell(npts, pts); } vtkIdType InsertQuad(vtkIdType *pts) { return m_QuadCells->InsertNextCell(4, pts); } vtkIdType InsertTetra(vtkIdType * /*pts*/) { return -1; } // ignored vtkIdType InsertHexahedron(vtkIdType * /*pts*/) { return -1; } // ignored }; // typedef typename MeshType::CellType CellType; // typedef typename itk::LineCell< CellType > LineType; // typedef typename itk::PolygonCell< CellType > PolygonType; // typedef typename itk::TriangleCell< CellType > TriangleType; typedef SwitchByCellType SingleCellArrayUserVisitorType; typedef SwitchByCellType DistributeUserVisitorType; typedef ExactSwitchByCellType ExactUserVisitorType; public: typedef itk::MatrixOffsetTransformBase ITKTransformType; typedef itk::MatrixOffsetTransformBase MITKTransformType; /*! Convert a MITK transformation to an ITK transformation Necessary because ITK uses double and MITK uses float values */ static void ConvertTransformToItk(const MITKTransformType *mitkTransform, ITKTransformType *itkTransform) { typename MITKTransformType::MatrixType mitkM = mitkTransform->GetMatrix(); typename ITKTransformType::MatrixType itkM; typename MITKTransformType::OffsetType mitkO = mitkTransform->GetOffset(); typename ITKTransformType::OffsetType itkO; for (short i = 0; i < 3; ++i) { for (short j = 0; j < 3; ++j) { itkM[i][j] = (double)mitkM[i][j]; } itkO[i] = (double)mitkO[i]; } itkTransform->SetMatrix(itkM); itkTransform->SetOffset(itkO); } /*! create an itkMesh object from a vtkPolyData */ static typename MeshType::Pointer MeshFromPolyData(vtkPolyData *poly, mitk::BaseGeometry *geometryFrame = nullptr, mitk::BaseGeometry *polyDataGeometryFrame = nullptr) { // Create a new mesh typename MeshType::Pointer output = MeshType::New(); output->SetCellsAllocationMethod(MeshType::CellsAllocatedDynamicallyCellByCell); typedef typename MeshType::CellDataContainer MeshCellDataContainerType; output->SetCellData(MeshCellDataContainerType::New()); // Get the points from vtk vtkPoints *vtkpoints = poly->GetPoints(); const unsigned int numPoints = poly->GetNumberOfPoints(); // Create a compatible point container for the mesh // the mesh is created with a null points container // MeshType::PointsContainer::Pointer points = // MeshType::PointsContainer::New(); // // Resize the point container to be able to fit the vtk points // points->Reserve(numPoints); // // Set the point container on the mesh // output->SetPoints(points); double vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if (geometryFrame == nullptr) { if (polyDataGeometryFrame == nullptr) { for (unsigned int i = 0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); // MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; // typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, itkPhysicalPoint); output->SetPoint(i, itkPhysicalPoint); } } else { for (unsigned int i = 0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); // MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; // typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::Point3D mitkWorldPoint; mitk::vtk2itk(vtkpoint, mitkWorldPoint); polyDataGeometryFrame->IndexToWorld(mitkWorldPoint, mitkWorldPoint); mitk::vtk2itk(mitkWorldPoint, itkPhysicalPoint); output->SetPoint(i, itkPhysicalPoint); } } } else { mitk::Point3D mitkWorldPoint; if (polyDataGeometryFrame == nullptr) { for (unsigned int i = 0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); // MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; // typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, mitkWorldPoint); geometryFrame->WorldToItkPhysicalPoint(mitkWorldPoint, itkPhysicalPoint); output->SetPoint(i, itkPhysicalPoint); } } else { for (unsigned int i = 0; i < numPoints; ++i) { vtkpoints->GetPoint(i, vtkpoint); // MITK_INFO << "next point: " << test[0]<< "," << test[1] << "," << test[2] << std::endl; // typename MeshType::PixelType* apoint = (typename MeshType::PixelType*) vtkpoints->GetPoint(i); mitk::vtk2itk(vtkpoint, mitkWorldPoint); polyDataGeometryFrame->IndexToWorld(mitkWorldPoint, mitkWorldPoint); geometryFrame->WorldToItkPhysicalPoint(mitkWorldPoint, itkPhysicalPoint); output->SetPoint(i, itkPhysicalPoint); } } } vtkCellArray *vtkcells = poly->GetPolys(); // vtkCellArray* vtkcells = poly->GetStrips(); // MeshType::CellsContainerPointer cells = MeshType::CellsContainer::New(); // output->SetCells(cells); // extract the cell id's from the vtkUnstructuredGrid int numcells = vtkcells->GetNumberOfCells(); int *vtkCellTypes = new int[numcells]; int cellId = 0; // poly ids start after verts and lines! int cellIdOfs = poly->GetNumberOfVerts() + poly->GetNumberOfLines(); for (; cellId < numcells; cellId++) { vtkCellTypes[cellId] = poly->GetCellType(cellId + cellIdOfs); } // cells->Reserve(numcells); vtkIdType npts; vtkIdType *pts; cellId = 0; typedef typename MeshType::MeshTraits OMeshTraits; typedef typename OMeshTraits::PixelType OPixelType; typedef typename MeshType::CellTraits CellTraits; typedef typename itk::CellInterface CellInterfaceType; typedef typename itk::TriangleCell TriCellType; typedef typename TriCellType::CellAutoPointer TriCellPointer; TriCellPointer newCell; output->GetCells()->Reserve(poly->GetNumberOfPolys() + poly->GetNumberOfStrips()); output->GetCellData()->Reserve(poly->GetNumberOfPolys() + poly->GetNumberOfStrips()); for (vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); cellId++) { switch (vtkCellTypes[cellId]) { case VTK_TRIANGLE: { if (npts != 3) continue; // skip non-triangles; - unsigned long pointIds[3]; + itk::IdentifierType pointIds[3]; pointIds[0] = (unsigned long)pts[0]; pointIds[1] = (unsigned long)pts[1]; pointIds[2] = (unsigned long)pts[2]; newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); //(unsigned long*)pts); output->SetCell(cellId, newCell); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } case VTK_QUAD: { if (npts != 4) continue; // skip non-quadrilateral - unsigned long pointIds[3]; + itk::IdentifierType pointIds[3]; pointIds[0] = (unsigned long)pts[0]; pointIds[1] = (unsigned long)pts[1]; pointIds[2] = (unsigned long)pts[2]; newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell); output->SetCellData(cellId, (typename MeshType::PixelType)3); cellId++; pointIds[0] = (unsigned long)pts[2]; pointIds[1] = (unsigned long)pts[3]; pointIds[2] = (unsigned long)pts[0]; newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } case VTK_EMPTY_CELL: { if (npts != 3) { MITK_ERROR << "Only empty triangle cell supported by now..." << std::endl; // skip non-triangle empty cells; continue; } - unsigned long pointIds[3]; + itk::IdentifierType pointIds[3]; pointIds[0] = (unsigned long)pts[0]; pointIds[1] = (unsigned long)pts[1]; pointIds[2] = (unsigned long)pts[2]; newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell); output->SetCellData(cellId, (typename MeshType::PixelType)3); break; } // case VTK_VERTEX: // If need to implement use // case VTK_POLY_VERTEX: // the poly->GetVerts() and // case VTK_LINE: // poly->GetLines() routines // case VTK_POLY_LINE: // outside of the switch..case. case VTK_POLYGON: case VTK_PIXEL: { if (npts != 4) continue; // skip non-quadrilateral - unsigned long pointIds[3]; + itk::IdentifierType pointIds[3]; for (unsigned int idx = 0; idx <= 1; idx++) { pointIds[0] = (unsigned long)pts[idx]; pointIds[1] = (unsigned long)pts[idx + 1]; pointIds[2] = (unsigned long)pts[idx + 2]; newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); output->SetCell(cellId + idx, newCell); output->SetCellData(cellId + idx, (typename MeshType::PixelType)3); } cellId++; break; } case VTK_TETRA: case VTK_VOXEL: case VTK_HEXAHEDRON: case VTK_WEDGE: case VTK_PYRAMID: case VTK_PARAMETRIC_CURVE: case VTK_PARAMETRIC_SURFACE: default: MITK_WARN << "Warning, unhandled cell type " << vtkCellTypes[cellId] << std::endl; } } if (poly->GetNumberOfStrips() != 0) { vtkcells = poly->GetStrips(); numcells = vtkcells->GetNumberOfCells(); vtkCellTypes = new int[numcells]; int stripId = 0; // strip ids start after verts, lines and polys! int stripIdOfs = poly->GetNumberOfVerts() + poly->GetNumberOfLines() + poly->GetNumberOfPolys(); for (; stripId < numcells; stripId++) { vtkCellTypes[stripId] = poly->GetCellType(stripId + stripIdOfs); } stripId = 0; vtkcells->InitTraversal(); while (vtkcells->GetNextCell(npts, pts)) { if (vtkCellTypes[stripId] != VTK_TRIANGLE_STRIP) { MITK_ERROR << "Only triangle strips supported!" << std::endl; continue; } stripId++; unsigned int numberOfTrianglesInStrip = npts - 2; - unsigned long pointIds[3]; + itk::IdentifierType pointIds[3]; pointIds[0] = (unsigned long)pts[0]; pointIds[1] = (unsigned long)pts[1]; pointIds[2] = (unsigned long)pts[2]; for (unsigned int t = 0; t < numberOfTrianglesInStrip; t++) { newCell.TakeOwnership(new TriCellType); newCell->SetPointIds(pointIds); output->SetCell(cellId, newCell); output->SetCellData(cellId, (typename MeshType::PixelType)3); cellId++; pointIds[0] = pointIds[1]; pointIds[1] = pointIds[2]; pointIds[2] = pts[t + 3]; } } } // output->Print(std::cout); output->BuildCellLinks(); delete[] vtkCellTypes; return output; } /*! create an itkMesh object from an mitk::Surface */ static typename MeshType::Pointer MeshFromSurface(mitk::Surface *surface, mitk::BaseGeometry *geometryFrame = nullptr) { if (surface == nullptr) return nullptr; return MeshFromPolyData(surface->GetVtkPolyData(), geometryFrame, surface->GetGeometry()); } /*! create an vtkUnstructuredGrid object from an itkMesh */ static vtkUnstructuredGrid *MeshToUnstructuredGrid(MeshType *mesh, bool usePointScalarAccessor = false, bool useCellScalarAccessor = false, unsigned int pointDataType = 0, mitk::BaseGeometry *geometryFrame = nullptr) { /*! default SingleCellArray line cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, SingleCellArrayUserVisitorType> SingleCellArrayLineVisitor; /*! default SingleCellArray polygon cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, SingleCellArrayUserVisitorType> SingleCellArrayPolygonVisitor; /*! default SingleCellArray triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::TriangleCell>, SingleCellArrayUserVisitorType> SingleCellArrayTriangleVisitor; /*! default SingleCellArray quad cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::QuadrilateralCell>, SingleCellArrayUserVisitorType> SingleCellArrayQuadrilateralVisitor; /*! default SingleCellArray tetra cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::TetrahedronCell>, SingleCellArrayUserVisitorType> SingleCellArrayTetrahedronVisitor; /*! default SingleCellArray hex cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::HexahedronCell>, SingleCellArrayUserVisitorType> SingleCellArrayHexahedronVisitor; // Get the number of points in the mesh int numPoints = mesh->GetNumberOfPoints(); if (numPoints == 0) { // mesh->Print(std::cerr); MITK_FATAL << "no points in Grid " << std::endl; exit(-1); } // Create a vtkUnstructuredGrid vtkUnstructuredGrid *vgrid = vtkUnstructuredGrid::New(); // Create the vtkPoints object and set the number of points vtkPoints *vpoints = vtkPoints::New(VTK_DOUBLE); vtkFloatArray *pointScalars = vtkFloatArray::New(); vtkFloatArray *cellScalars = vtkFloatArray::New(); pointScalars->SetNumberOfComponents(1); cellScalars->SetNumberOfComponents(1); typename MeshType::PointsContainer::Pointer points = mesh->GetPoints(); typename MeshType::PointsContainer::Iterator i; // iterate over all the points in the itk mesh to find // the maximal index unsigned int maxIndex = 0; for (i = points->Begin(); i != points->End(); ++i) { if (maxIndex < i->Index()) maxIndex = i->Index(); } // initialize vtk-classes for points and scalars vpoints->SetNumberOfPoints(maxIndex + 1); pointScalars->SetNumberOfTuples(maxIndex + 1); cellScalars->SetNumberOfTuples(mesh->GetNumberOfCells()); double vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if (geometryFrame == 0) { for (i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); mitk::itk2vtk(itkPhysicalPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk vpoints->SetPoint(idx, vtkpoint); if (usePointScalarAccessor) { pointScalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar(mesh->GetPointData(), i->Index(), mesh, pointDataType)); } } } else { mitk::Point3D mitkWorldPoint; for (i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); geometryFrame->ItkPhysicalPointToWorld(itkPhysicalPoint, mitkWorldPoint); mitk::itk2vtk(mitkWorldPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk vpoints->SetPoint(idx, vtkpoint); if (usePointScalarAccessor) { pointScalars->InsertTuple1( idx, ScalarAccessor::GetPointScalar(mesh->GetPointData(), i->Index(), mesh, pointDataType)); } } } // Set the points on the vtk grid vgrid->SetPoints(vpoints); if (usePointScalarAccessor) vgrid->GetPointData()->SetScalars(pointScalars); // Now create the cells using the MultiVisitor // 1. Create a MultiVisitor typename MeshType::CellType::MultiVisitor::Pointer mv = MeshType::CellType::MultiVisitor::New(); // 2. Create visitors typename SingleCellArrayLineVisitor::Pointer lv = SingleCellArrayLineVisitor::New(); typename SingleCellArrayPolygonVisitor::Pointer pv = SingleCellArrayPolygonVisitor::New(); typename SingleCellArrayTriangleVisitor::Pointer tv = SingleCellArrayTriangleVisitor::New(); typename SingleCellArrayQuadrilateralVisitor::Pointer qv = SingleCellArrayQuadrilateralVisitor::New(); typename SingleCellArrayTetrahedronVisitor::Pointer tetv = SingleCellArrayTetrahedronVisitor::New(); typename SingleCellArrayHexahedronVisitor::Pointer hv = SingleCellArrayHexahedronVisitor::New(); // 3. Set up the visitors // int vtkCellCount = 0; // running counter for current cell being inserted into vtk int numCells = mesh->GetNumberOfCells(); int *types = new int[numCells]; // type array for vtk // create vtk cells and estimate the size vtkCellArray *cells = vtkCellArray::New(); cells->Allocate(numCells); // Set the TypeArray CellCount and CellArray for the visitors lv->SetTypeArray(types); lv->SetCellArray(cells); pv->SetTypeArray(types); pv->SetCellArray(cells); tv->SetTypeArray(types); // tv->SetCellCounter(&vtkCellCount); tv->SetCellArray(cells); qv->SetTypeArray(types); // qv->SetCellCounter(&vtkCellCount); qv->SetCellArray(cells); tetv->SetTypeArray(types); tetv->SetCellArray(cells); hv->SetTypeArray(types); hv->SetCellArray(cells); if (useCellScalarAccessor) { lv->SetUseCellScalarAccessor(true); lv->SetCellScalars(cellScalars); lv->SetMeshCellData(mesh->GetCellData()); pv->SetUseCellScalarAccessor(true); pv->SetCellScalars(cellScalars); pv->SetMeshCellData(mesh->GetCellData()); tv->SetUseCellScalarAccessor(true); tv->SetCellScalars(cellScalars); tv->SetMeshCellData(mesh->GetCellData()); qv->SetUseCellScalarAccessor(true); qv->SetCellScalars(cellScalars); qv->SetMeshCellData(mesh->GetCellData()); tetv->SetUseCellScalarAccessor(true); tetv->SetCellScalars(cellScalars); tetv->SetMeshCellData(mesh->GetCellData()); hv->SetUseCellScalarAccessor(true); hv->SetCellScalars(cellScalars); hv->SetMeshCellData(mesh->GetCellData()); } // add the visitors to the multivisitor mv->AddVisitor(lv); mv->AddVisitor(pv); mv->AddVisitor(tv); mv->AddVisitor(qv); mv->AddVisitor(tetv); mv->AddVisitor(hv); // Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // Now set the cells on the vtk grid with the type array and cell array vgrid->SetCells(types, cells); vgrid->GetCellData()->SetScalars(cellScalars); // Clean up vtk objects (no vtkSmartPointer ... ) cells->Delete(); vpoints->Delete(); delete[] types; pointScalars->Delete(); cellScalars->Delete(); // MITK_INFO << "meshToUnstructuredGrid end" << std::endl; return vgrid; } /*! create a vtkPolyData object from an itkMesh */ static vtkPolyData *MeshToPolyData(MeshType *mesh, bool onlyTriangles = false, bool useScalarAccessor = false, unsigned int pointDataType = 0, mitk::BaseGeometry *geometryFrame = nullptr, vtkPolyData *polydata = nullptr) { /*! default Distribute line cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, DistributeUserVisitorType> DistributeLineVisitor; /*! default Distribute polygon cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation, DistributeUserVisitorType> DistributePolygonVisitor; /*! default Distribute triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::TriangleCell>, DistributeUserVisitorType> DistributeTriangleVisitor; /*! default Distribute quad cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::QuadrilateralCell>, DistributeUserVisitorType> DistributeQuadrilateralVisitor; /*! default Distribute triangle cell visitior definition */ typedef typename itk::CellInterfaceVisitorImplementation< typename MeshType::CellPixelType, typename MeshType::CellTraits, itk::TriangleCell>, ExactUserVisitorType> ExactTriangleVisitor; // Get the number of points in the mesh int numPoints = mesh->GetNumberOfPoints(); if (numPoints == 0) { // mesh->Print(std::cerr); MITK_ERROR << "no points in Grid " << std::endl; } // Create a vtkPolyData if (polydata == nullptr) polydata = vtkPolyData::New(); else polydata->Initialize(); // Create the vtkPoints object and set the number of points vtkPoints *vpoints = vtkPoints::New(VTK_DOUBLE); vtkFloatArray *scalars = vtkFloatArray::New(); scalars->SetNumberOfComponents(1); typename MeshType::PointsContainer::Pointer points = mesh->GetPoints(); typename MeshType::PointsContainer::Iterator i; // iterate over all the points in the itk mesh to find // the maximal index unsigned int maxIndex = 0; for (i = points->Begin(); i != points->End(); ++i) { if (maxIndex < i->Index()) maxIndex = i->Index(); } // initialize vtk-classes for points and scalars vpoints->SetNumberOfPoints(maxIndex + 1); scalars->SetNumberOfTuples(maxIndex + 1); // iterate over all the points in the itk mesh filling in // the vtkPoints object as we go double vtkpoint[3]; typename MeshType::PointType itkPhysicalPoint; if (geometryFrame == nullptr) { for (i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); mitk::itk2vtk(itkPhysicalPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk // itk returns a const pointer, but vtk is not const correct, so // we have to use a const cast to get rid of the const // vpoints->SetPoint(idx, const_cast(i->Value().GetDataPointer())); vpoints->SetPoint(idx, vtkpoint); if (useScalarAccessor) { scalars->InsertTuple1(idx, ScalarAccessor::GetPointScalar(mesh->GetPointData(), i->Index(), mesh, pointDataType)); } } } else { mitk::Point3D mitkWorldPoint; for (i = points->Begin(); i != points->End(); ++i) { // Get the point index from the point container iterator int idx = i->Index(); itkPhysicalPoint = i->Value(); geometryFrame->ItkPhysicalPointToWorld(itkPhysicalPoint, mitkWorldPoint); mitk::itk2vtk(mitkWorldPoint, vtkpoint); // Set the vtk point at the index with the the coord array from itk // itk returns a const pointer, but vtk is not const correct, so // we have to use a const cast to get rid of the const // vpoints->SetPoint(idx, const_cast(i->Value().GetDataPointer())); vpoints->SetPoint(idx, vtkpoint); if (useScalarAccessor) { scalars->InsertTuple1(idx, ScalarAccessor::GetPointScalar(mesh->GetPointData(), i->Index(), mesh, pointDataType)); } } } // Set the points on the vtk grid polydata->SetPoints(vpoints); if (useScalarAccessor) polydata->GetPointData()->SetScalars(scalars); polydata->GetPointData()->CopyAllOn(); // Now create the cells using the MulitVisitor // 1. Create a MultiVisitor typedef typename MeshType::CellType::MultiVisitor MeshMV; typename MeshMV::Pointer mv = MeshMV::New(); int numCells = mesh->GetNumberOfCells(); if (onlyTriangles) { // create vtk cells and allocate vtkCellArray *trianglecells = vtkCellArray::New(); trianglecells->Allocate(numCells); // 2. Create a triangle visitor and add it to the multivisitor typename ExactTriangleVisitor::Pointer tv = ExactTriangleVisitor::New(); tv->SetCellArrays(nullptr, trianglecells, nullptr, nullptr); mv->AddVisitor(tv); // 3. Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // 4. Set the result into our vtkPolyData if (trianglecells->GetNumberOfCells() > 0) polydata->SetStrips(trianglecells); // 5. Clean up vtk objects (no vtkSmartPointer ... ) trianglecells->Delete(); } else { // create vtk cells and allocate vtkCellArray *linecells = vtkCellArray::New(); vtkCellArray *trianglecells = vtkCellArray::New(); vtkCellArray *polygoncells = vtkCellArray::New(); linecells->Allocate(numCells); trianglecells->Allocate(numCells); polygoncells->Allocate(numCells); // 2. Create visitors typename DistributeLineVisitor::Pointer lv = DistributeLineVisitor::New(); typename DistributePolygonVisitor::Pointer pv = DistributePolygonVisitor::New(); typename DistributeTriangleVisitor::Pointer tv = DistributeTriangleVisitor::New(); typename DistributeQuadrilateralVisitor::Pointer qv = DistributeQuadrilateralVisitor::New(); lv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); pv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); tv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); qv->SetCellArrays(linecells, trianglecells, polygoncells, polygoncells); // add the visitors to the multivisitor mv->AddVisitor(tv); mv->AddVisitor(lv); mv->AddVisitor(pv); mv->AddVisitor(qv); // 3. Now ask the mesh to accept the multivisitor which // will Call Visit for each cell in the mesh that matches the // cell types of the visitors added to the MultiVisitor mesh->Accept(mv); // 4. Set the result into our vtkPolyData if (linecells->GetNumberOfCells() > 0) polydata->SetLines(linecells); if (trianglecells->GetNumberOfCells() > 0) polydata->SetStrips(trianglecells); if (polygoncells->GetNumberOfCells() > 0) polydata->SetPolys(polygoncells); // 5. Clean up vtk objects (no vtkSmartPointer ... ) linecells->Delete(); trianglecells->Delete(); polygoncells->Delete(); } vpoints->Delete(); scalars->Delete(); // MITK_INFO << "meshToPolyData end" << std::endl; return polydata; } static typename MeshType::Pointer CreateRegularSphereMesh(typename MeshType::PointType center, typename MeshType::PointType::VectorType scale, int resolution) { typedef itk::RegularSphereMeshSource SphereSourceType; typename SphereSourceType::Pointer mySphereSource = SphereSourceType::New(); mySphereSource->SetCenter(center); mySphereSource->SetScale(scale); mySphereSource->SetResolution(resolution); mySphereSource->Update(); typename MeshType::Pointer resultMesh = mySphereSource->GetOutput(); resultMesh->Register(); // necessary ???? return resultMesh; } static typename MeshType::Pointer CreateSphereMesh(typename MeshType::PointType center, typename MeshType::PointType scale, int *resolution) { typedef typename itk::SphereMeshSource SphereSource; typename SphereSource::Pointer mySphereSource = SphereSource::New(); mySphereSource->SetCenter(center); mySphereSource->SetScale(scale); mySphereSource->SetResolutionX(resolution[0]); mySphereSource->SetResolutionY(resolution[1]); mySphereSource->SetSquareness1(1); mySphereSource->SetSquareness2(1); mySphereSource->Update(); mySphereSource->GetOutput(); typename MeshType::Pointer resultMesh = mySphereSource->GetOutput(); resultMesh->Register(); return resultMesh; } // static typename MeshType::Pointer TranslateMesh(typename MeshType::PointType vec, MeshType* input) // { // // typename MeshType::Pointer output = MeshType::New(); // { // output->SetPoints(input->GetPoints()); // output->SetPointData(input->GetPointData()); // output->SetCells(input->GetCells()); // output->SetLastCellId( input->GetLastCellId() ); // typename MeshType::GeometryMapIterator pointDataIterator = input->GetGeometryData()->Begin(); // typename MeshType::GeometryMapIterator pointDataEnd = input->GetGeometryData()->End(); // // typename MeshType::PointType inputPoint,outputPoint; // // while (pointDataIterator != pointDataEnd) // { // unsigned long pointId = pointDataIterator->Index(); // itk::SimplexMeshGeometry* newGeometry = new itk::SimplexMeshGeometry(); // itk::SimplexMeshGeometry* refGeometry = pointDataIterator->Value(); // // input->GetPoint(pointId, &inputPoint ); // outputPoint[0] = inputPoint[0] + vec[0]; // outputPoint[1] = inputPoint[1] + vec[1]; // outputPoint[2] = inputPoint[2] + vec[2]; // output->SetPoint( pointId, outputPoint ); // // // newGeometry->pos = outputPoint; // newGeometry->neighborIndices = refGeometry->neighborIndices; // newGeometry->meanCurvature = refGeometry->meanCurvature; // newGeometry->neighbors = refGeometry->neighbors; // newGeometry->oldPos = refGeometry->oldPos; // newGeometry->eps = refGeometry->eps; // newGeometry->referenceMetrics = refGeometry->referenceMetrics; // newGeometry->neighborSet = refGeometry->neighborSet; // newGeometry->distance = refGeometry->distance; // newGeometry->externalForce = refGeometry->externalForce; // newGeometry->internalForce = refGeometry->internalForce; // output->SetGeometryData(pointId, newGeometry); // pointDataIterator++; // } // } //// output->SetGeometryData( inputMesh->GetGeometryData() ); // return output; // } static typename MeshType::Pointer CreateRegularSphereMesh2(typename MeshType::PointType center, typename MeshType::PointType scale, int resolution) { typedef typename itk::AutomaticTopologyMeshSource MeshSourceType; typename MeshSourceType::Pointer mySphereSource = MeshSourceType::New(); typename MeshType::PointType pnt0, pnt1, pnt2, pnt3, pnt4, pnt5, pnt6, pnt7, pnt8, pnt9, pnt10, pnt11; double c1 = 0.5 * (1.0 + sqrt(5.0)); double c2 = 1.0; double len = sqrt(c1 * c1 + c2 * c2); c1 /= len; c2 /= len; pnt0[0] = center[0] - c1 * scale[0]; pnt0[1] = center[1]; pnt0[2] = center[2] + c2 * scale[2]; pnt1[0] = center[0]; pnt1[1] = center[1] + c2 * scale[1]; pnt1[2] = center[2] - c1 * scale[2]; pnt2[0] = center[0]; pnt2[1] = center[1] + c2 * scale[1]; pnt2[2] = center[2] + c1 * scale[2]; pnt3[0] = center[0] + c1 * scale[0]; pnt3[1] = center[1]; pnt3[2] = center[2] - c2 * scale[2]; pnt4[0] = center[0] - c2 * scale[0]; pnt4[1] = center[1] - c1 * scale[1]; pnt4[2] = center[2]; pnt5[0] = center[0] - c2 * scale[0]; pnt5[1] = center[1] + c1 * scale[1]; pnt5[2] = center[2]; pnt6[0] = center[0]; pnt6[1] = center[1] - c2 * scale[1]; pnt6[2] = center[2] + c1 * scale[2]; pnt7[0] = center[0] + c2 * scale[0]; pnt7[1] = center[1] + c1 * scale[1]; pnt7[2] = center[2]; pnt8[0] = center[0]; pnt8[1] = center[1] - c2 * scale[1]; pnt8[2] = center[2] - c1 * scale[2]; pnt9[0] = center[0] + c1 * scale[0]; pnt9[1] = center[1]; pnt9[2] = center[2] + c2 * scale[2]; pnt10[0] = center[0] + c2 * scale[0]; pnt10[1] = center[1] - c1 * scale[1]; pnt10[2] = center[2]; pnt11[0] = center[0] - c1 * scale[0]; pnt11[1] = center[1]; pnt11[2] = center[2] - c2 * scale[2]; addTriangle(mySphereSource, scale, pnt9, pnt2, pnt6, resolution); addTriangle(mySphereSource, scale, pnt1, pnt11, pnt5, resolution); addTriangle(mySphereSource, scale, pnt11, pnt1, pnt8, resolution); addTriangle(mySphereSource, scale, pnt0, pnt11, pnt4, resolution); addTriangle(mySphereSource, scale, pnt3, pnt1, pnt7, resolution); addTriangle(mySphereSource, scale, pnt3, pnt8, pnt1, resolution); addTriangle(mySphereSource, scale, pnt9, pnt3, pnt7, resolution); addTriangle(mySphereSource, scale, pnt0, pnt6, pnt2, resolution); addTriangle(mySphereSource, scale, pnt4, pnt10, pnt6, resolution); addTriangle(mySphereSource, scale, pnt1, pnt5, pnt7, resolution); addTriangle(mySphereSource, scale, pnt7, pnt5, pnt2, resolution); addTriangle(mySphereSource, scale, pnt8, pnt3, pnt10, resolution); addTriangle(mySphereSource, scale, pnt4, pnt11, pnt8, resolution); addTriangle(mySphereSource, scale, pnt9, pnt7, pnt2, resolution); addTriangle(mySphereSource, scale, pnt10, pnt9, pnt6, resolution); addTriangle(mySphereSource, scale, pnt0, pnt5, pnt11, resolution); addTriangle(mySphereSource, scale, pnt0, pnt2, pnt5, resolution); addTriangle(mySphereSource, scale, pnt8, pnt10, pnt4, resolution); addTriangle(mySphereSource, scale, pnt3, pnt9, pnt10, resolution); addTriangle(mySphereSource, scale, pnt6, pnt0, pnt4, resolution); return mySphereSource->GetOutput(); } private: static void addTriangle(typename itk::AutomaticTopologyMeshSource::Pointer meshSource, typename MeshType::PointType scale, typename MeshType::PointType pnt0, typename MeshType::PointType pnt1, typename MeshType::PointType pnt2, int resolution) { if (resolution == 0) { // add triangle meshSource->AddTriangle(meshSource->AddPoint(pnt0), meshSource->AddPoint(pnt1), meshSource->AddPoint(pnt2)); } else { vnl_vector_fixed v1, v2, res, pv; v1 = (pnt1 - pnt0).Get_vnl_vector(); v2 = (pnt2 - pnt0).Get_vnl_vector(); res = vnl_cross_3d(v1, v2); pv = pnt0.GetVectorFromOrigin().Get_vnl_vector(); // double d = res[0]*pv[0] + res[1]*pv[1] + res[2]*pv[2]; // subdivision typename MeshType::PointType pnt01, pnt12, pnt20; for (int d = 0; d < 3; d++) { pnt01[d] = (pnt0[d] + pnt1[d]) / 2.0; pnt12[d] = (pnt1[d] + pnt2[d]) / 2.0; pnt20[d] = (pnt2[d] + pnt0[d]) / 2.0; } // map new points to sphere double lenPnt01 = 0; for (int d = 0; d < 3; d++) lenPnt01 += pnt01[d] * pnt01[d]; lenPnt01 = sqrt(lenPnt01); double lenPnt12 = 0; for (int d = 0; d < 3; d++) lenPnt12 += pnt12[d] * pnt12[d]; lenPnt12 = sqrt(lenPnt12); double lenPnt20 = 0; for (int d = 0; d < 3; d++) lenPnt20 += pnt20[d] * pnt20[d]; lenPnt20 = sqrt(lenPnt20); for (int d = 0; d < 3; d++) { pnt01[d] *= scale[d] / lenPnt01; pnt12[d] *= scale[d] / lenPnt12; pnt20[d] *= scale[d] / lenPnt20; } addTriangle(meshSource, scale, pnt0, pnt01, pnt20, resolution - 1); addTriangle(meshSource, scale, pnt01, pnt1, pnt12, resolution - 1); addTriangle(meshSource, scale, pnt20, pnt12, pnt2, resolution - 1); addTriangle(meshSource, scale, pnt01, pnt12, pnt20, resolution - 1); } } }; #endif // MITKMESHUTIL_H_INCLUDED diff --git a/Modules/ModuleList.cmake b/Modules/ModuleList.cmake index 589eed5b3f..98b9304361 100644 --- a/Modules/ModuleList.cmake +++ b/Modules/ModuleList.cmake @@ -1,78 +1,78 @@ # The entries in the mitk_modules list must be # ordered according to their dependencies. -set(mitk_modules +set(MITK_MODULES Core CommandLine AppUtil DCMTesting RDF LegacyIO DataTypesExt Annotation LegacyGL AlgorithmsExt MapperExt DICOMReader DICOMReaderServices DICOMTesting SceneSerializationBase PlanarFigure ImageDenoising ImageExtraction SceneSerialization Gizmo GraphAlgorithms Multilabel ImageStatistics ContourModel SurfaceInterpolation Segmentation PlanarFigureSegmentation QtWidgets QtWidgetsExt Chart SegmentationUI Classification GPGPU OpenIGTLink IGTBase IGT CameraCalibration OpenCL OpenCVVideoSupport QtOverlays ToFHardware ToFProcessing ToFUI PhotoacousticsHardware PhotoacousticsAlgorithms PhotoacousticsLib US USUI DicomUI Remeshing Python QtPython Persistence OpenIGTLinkUI IGTUI DicomRT RTUI IOExt XNAT TubeGraph BiophotonicsHardware MatchPointRegistration MatchPointRegistrationUI DiffusionImaging TumorInvasionAnalysis BoundingShape RenderWindowManager RenderWindowManagerUI CEST ) if(MITK_ENABLE_PIC_READER) - list(APPEND mitk_modules IpPicSupportIO) + list(APPEND MITK_MODULES IpPicSupportIO) endif() diff --git a/SuperBuild.cmake b/SuperBuild.cmake index a9ddf083e7..134c3f04e9 100644 --- a/SuperBuild.cmake +++ b/SuperBuild.cmake @@ -1,442 +1,454 @@ include(mitkFunctionInstallExternalCMakeProject) #----------------------------------------------------------------------------- # Convenient macro allowing to download a file #----------------------------------------------------------------------------- if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL) set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty) endif() macro(downloadFile url dest) file(DOWNLOAD ${url} ${dest} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() endmacro() #----------------------------------------------------------------------------- # MITK Prerequisites #----------------------------------------------------------------------------- if(UNIX AND NOT APPLE) include(mitkFunctionCheckPackageHeader) # Check for libxt-dev mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/) # Check for libtiff4-dev mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev) # Check for libwrap0-dev mitkFunctionCheckPackageHeader(tcpd.h libwrap0-dev) endif() # We need a proper patch program. On Linux and MacOS, we assume # that "patch" is available. On Windows, we download patch.exe # if not patch program is found. find_program(PATCH_COMMAND patch) if((NOT PATCH_COMMAND OR NOT EXISTS ${PATCH_COMMAND}) AND WIN32) downloadFile(${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/patch.exe ${CMAKE_CURRENT_BINARY_DIR}/patch.exe) find_program(PATCH_COMMAND patch ${CMAKE_CURRENT_BINARY_DIR}) endif() if(NOT PATCH_COMMAND) message(FATAL_ERROR "No patch program found.") endif() #----------------------------------------------------------------------------- # ExternalProjects #----------------------------------------------------------------------------- get_property(external_projects GLOBAL PROPERTY MITK_EXTERNAL_PROJECTS) if(MITK_CTEST_SCRIPT_MODE) # Write a file containing the list of enabled external project targets. # This file can be read by a ctest script to separately build projects. set(SUPERBUILD_TARGETS ) foreach(proj ${external_projects}) if(MITK_USE_${proj}) list(APPEND SUPERBUILD_TARGETS ${proj}) endif() endforeach() file(WRITE "${CMAKE_BINARY_DIR}/SuperBuildTargets.cmake" "set(SUPERBUILD_TARGETS ${SUPERBUILD_TARGETS})") endif() # A list of "nice" external projects, playing well together with CMake set(nice_external_projects ${external_projects}) list(REMOVE_ITEM nice_external_projects Boost Python) foreach(proj ${nice_external_projects}) if(MITK_USE_${proj}) set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory") mark_as_advanced(EXTERNAL_${proj}_DIR) if(EXTERNAL_${proj}_DIR) set(${proj}_DIR ${EXTERNAL_${proj}_DIR}) endif() endif() endforeach() set(EXTERNAL_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory") mark_as_advanced(EXTERNAL_BOOST_ROOT) if(EXTERNAL_BOOST_ROOT) set(BOOST_ROOT ${EXTERNAL_BOOST_ROOT}) endif() # Setup file for setting custom ctest vars configure_file( CMake/SuperbuildCTestCustom.cmake.in ${MITK_BINARY_DIR}/CTestCustom.cmake @ONLY ) if(BUILD_TESTING) set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory") mark_as_advanced(EXTERNAL_MITK_DATA_DIR) if(EXTERNAL_MITK_DATA_DIR) set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR}) endif() endif() #----------------------------------------------------------------------------- # External project settings #----------------------------------------------------------------------------- include(ExternalProject) set(ep_prefix "${CMAKE_BINARY_DIR}/ep") set_property(DIRECTORY PROPERTY EP_PREFIX ${ep_prefix}) # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(gen "${CMAKE_GENERATOR}") endif() # Use this value where semi-colons are needed in ep_add args: set(sep "^^") ## if(MSVC_VERSION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP") endif() # This is a workaround for passing linker flags # actually down to the linker invocation set(_cmake_required_flags_orig ${CMAKE_REQUIRED_FLAGS}) set(CMAKE_REQUIRED_FLAGS "-Wl,-rpath") mitkFunctionCheckCompilerFlags(${CMAKE_REQUIRED_FLAGS} _has_rpath_flag) set(CMAKE_REQUIRED_FLAGS ${_cmake_required_flags_orig}) set(_install_rpath_linkflag ) if(_has_rpath_flag) if(APPLE) set(_install_rpath_linkflag "-Wl,-rpath,@loader_path/../lib") else() set(_install_rpath_linkflag "-Wl,-rpath='$ORIGIN/../lib'") endif() endif() set(_install_rpath) if(APPLE) set(_install_rpath "@loader_path/../lib") elseif(UNIX) # this work for libraries as well as executables set(_install_rpath "\$ORIGIN/../lib") endif() set(ep_common_args -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_MACOSX_RPATH:BOOL=TRUE "-DCMAKE_INSTALL_RPATH:STRING=${_install_rpath}" -DBUILD_TESTING:BOOL=OFF -DCMAKE_INSTALL_PREFIX:PATH= -DBUILD_SHARED_LIBS:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_CXX14_FLAG}" #debug flags -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} #release flags -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} #relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} #link flags -DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} -DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ) set(DCMTK_CMAKE_DEBUG_POSTFIX ) # python libraries wont work with it if(NOT MITK_USE_Python) list(APPEND ep_common_args -DCMAKE_DEBUG_POSTFIX:STRING=d) set(DCMTK_CMAKE_DEBUG_POSTFIX d) endif() set(ep_common_cache_args ) set(ep_common_cache_default_args "-DCMAKE_PREFIX_PATH:PATH=;${CMAKE_PREFIX_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" ) # Pass the CMAKE_OSX variables to external projects if(APPLE) set(MAC_OSX_ARCHITECTURE_ARGS -DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT} ) set(ep_common_args ${MAC_OSX_ARCHITECTURE_ARGS} ${ep_common_args} ) endif() set(mitk_superbuild_ep_args) set(mitk_depends ) # Include external projects include(CMakeExternals/MITKData.cmake) foreach(p ${external_projects}) - include(CMakeExternals/${p}.cmake) + if(EXISTS ${CMAKE_SOURCE_DIR}/CMakeExternals/${p}.cmake) + include(CMakeExternals/${p}.cmake) + else() + foreach(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIRS}) + get_filename_component(MITK_EXTENSION_DIR ${MITK_EXTENSION_DIR} ABSOLUTE) + set(MITK_CMAKE_EXTERNALS_EXTENSION_DIR ${MITK_EXTENSION_DIR}/CMakeExternals) + if(EXISTS ${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/${p}.cmake) + include(${MITK_CMAKE_EXTERNALS_EXTENSION_DIR}/${p}.cmake) + break() + endif() + endforeach() + endif() list(APPEND mitk_superbuild_ep_args -DMITK_USE_${p}:BOOL=${MITK_USE_${p}} ) get_property(_package GLOBAL PROPERTY MITK_${p}_PACKAGE) if(_package) list(APPEND mitk_superbuild_ep_args -D${p}_DIR:PATH=${${p}_DIR}) endif() list(APPEND mitk_depends ${${p}_DEPENDS}) endforeach() #----------------------------------------------------------------------------- # Set superbuild boolean args #----------------------------------------------------------------------------- set(mitk_cmake_boolean_args BUILD_SHARED_LIBS WITH_COVERAGE BUILD_TESTING MITK_BUILD_ALL_PLUGINS MITK_BUILD_ALL_APPS MITK_BUILD_EXAMPLES MITK_USE_Qt5 MITK_USE_Qt5_WebEngine MITK_USE_SYSTEM_Boost MITK_USE_BLUEBERRY MITK_USE_OpenCL MITK_ENABLE_PIC_READER ) #----------------------------------------------------------------------------- # Create the final variable containing superbuild boolean args #----------------------------------------------------------------------------- set(mitk_superbuild_boolean_args) foreach(mitk_cmake_arg ${mitk_cmake_boolean_args}) list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}}) endforeach() if(MITK_BUILD_ALL_PLUGINS) list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON) endif() #----------------------------------------------------------------------------- # MITK Utilities #----------------------------------------------------------------------------- set(proj MITK-Utilities) ExternalProject_Add(${proj} DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS ${mitk_depends} ) #----------------------------------------------------------------------------- # Additional MITK CXX/C Flags #----------------------------------------------------------------------------- set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK") set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE) set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK") set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK") mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE) set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK") set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK") set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK") mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS) #----------------------------------------------------------------------------- # MITK Configure #----------------------------------------------------------------------------- if(MITK_INITIAL_CACHE_FILE) set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}") endif() set(mitk_optional_cache_args ) foreach(type RUNTIME ARCHIVE LIBRARY) if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) endif() endforeach() # Optional python variables if(MITK_USE_Python) list(APPEND mitk_optional_cache_args -DMITK_USE_Python:BOOL=${MITK_USE_Python} -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DMITK_USE_SYSTEM_PYTHON:BOOL=${MITK_USE_SYSTEM_PYTHON} ) endif() if(Eigen_INCLUDE_DIR) list(APPEND mitk_optional_cache_args -DEigen_INCLUDE_DIR:PATH=${Eigen_INCLUDE_DIR} ) endif() set(proj MITK-Configure) ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} DOWNLOAD_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_CACHE_ARGS # --------------- Build options ---------------- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_INSTALL_PREFIX} -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} "-DCMAKE_PREFIX_PATH:PATH=${ep_prefix};${CMAKE_PREFIX_PATH}" "-DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH}" "-DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH}" # --------------- Compile options ---------------- -DCMAKE_CXX_EXTENSIONS:STRING=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_STANDARD_REQUIRED:BOOL=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}" "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}" # debug flags "-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}" "-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}" # release flags "-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}" "-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}" # relwithdebinfo -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO} # link flags "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}" "-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}" "-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}" # Output directories -DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY} -DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY} -DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY} # ------------- Boolean build options -------------- ${mitk_superbuild_boolean_args} ${mitk_optional_cache_args} -DMITK_USE_SUPERBUILD:BOOL=OFF -DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION} -DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS} # ----------------- Miscellaneous --------------- -DCMAKE_LIBRARY_PATH:PATH=${CMAKE_LIBRARY_PATH} -DCMAKE_INCLUDE_PATH:PATH=${CMAKE_INCLUDE_PATH} -DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE} -DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR} -DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD} -DMITK_WHITELIST:STRING=${MITK_WHITELIST} -DMITK_WHITELISTS_EXTERNAL_PATH:STRING=${MITK_WHITELISTS_EXTERNAL_PATH} -DMITK_WHITELISTS_INTERNAL_PATH:STRING=${MITK_WHITELISTS_INTERNAL_PATH} + -DMITK_EXTENSION_DIRS:STRING=${MITK_EXTENSION_DIRS} -DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES} -DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES} -DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES} -DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES} -DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS} # --------------- External project options --------------- -DMITK_DATA_DIR:PATH=${MITK_DATA_DIR} -DMITK_EXTERNAL_PROJECT_PREFIX:PATH=${ep_prefix} -DCppMicroServices_DIR:PATH=${CppMicroServices_DIR} -DDCMTK_CMAKE_DEBUG_POSTFIX:STRING=${DCMTK_CMAKE_DEBUG_POSTFIX} -DBOOST_ROOT:PATH=${BOOST_ROOT} -DBOOST_LIBRARYDIR:PATH=${BOOST_LIBRARYDIR} -DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES} CMAKE_ARGS ${mitk_initial_cache_arg} ${MAC_OSX_ARCHITECTURE_ARGS} ${mitk_superbuild_ep_args} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build BUILD_COMMAND "" INSTALL_COMMAND "" DEPENDS MITK-Utilities ) mitkFunctionInstallExternalCMakeProject(${proj}) #----------------------------------------------------------------------------- # MITK #----------------------------------------------------------------------------- if(CMAKE_GENERATOR MATCHES ".*Makefiles.*") set(mitk_build_cmd "$(MAKE)") else() set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR}) endif() if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET) set(MITKBUILD_TARGET_ALL_OPTION "ALL") else() set(MITKBUILD_TARGET_ALL_OPTION "") endif() add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION} COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build DEPENDS MITK-Configure ) #----------------------------------------------------------------------------- # Custom target allowing to drive the build of the MITK project itself #----------------------------------------------------------------------------- add_custom_target(MITK COMMAND ${mitk_build_cmd} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build )