diff --git a/CMake/FindNumpy.cmake b/CMake/FindNumpy.cmake
new file mode 100644
index 0000000000..4170adb613
--- /dev/null
+++ b/CMake/FindNumpy.cmake
@@ -0,0 +1,29 @@
+# Variables set by this script
+# NUMPY_FOUND
+# NUMPY_INCLUDE_DIR
+
+find_package(PackageHandleStandardArgs)
+
+# numpy dir defined, own numpy deployed in python runtime
+if(DEFINED Numpy_DIR AND EXISTS ${Numpy_DIR})
+ if(EXISTS ${Numpy_DIR}/core/include)
+ set(NUMPY_INCLUDE_DIR ${Numpy_DIR}/core/include)
+ endif()
+else() #numpy dir not defined
+ execute_process (
+ COMMAND ${PYTHON_EXECUTABLE} -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print numpy.distutils.misc_util.get_numpy_include_dirs()[0]"
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+
+ if(DEFINED output AND EXISTS ${output} )
+ set (NUMPY_INCLUDE_DIR ${output})
+ endif()
+endif()
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Numpy DEFAULT_MSG NUMPY_INCLUDE_DIR)
+
+MARK_AS_ADVANCED (
+ NUMPY_INCLUDE_DIR
+)
+
diff --git a/CMake/MITKDashboardSetup.cmake b/CMake/MITKDashboardSetup.cmake
index caf521922a..c1b322fc43 100644
--- a/CMake/MITKDashboardSetup.cmake
+++ b/CMake/MITKDashboardSetup.cmake
@@ -1,193 +1,197 @@
# This file is intended to be included at the end of a custom MITKDashboardScript.TEMPLATE.cmake file
list(APPEND CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
#
# Automatically determined properties
#
set(MY_OPERATING_SYSTEM )
if(UNIX)
# Download a utility script
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/mitkDetectOS.sh;hb=${hb}")
set(dest "${CTEST_SCRIPT_DIRECTORY}/mitkDetectOS.sh")
downloadFile("${url}" "${dest}")
execute_process(COMMAND sh "${dest}"
RESULT_VARIABLE _result OUTPUT_VARIABLE _out
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _result)
set(MY_OPERATING_SYSTEM "${_out}")
endif()
endif()
if(NOT MY_OPERATING_SYSTEM)
set(MY_OPERATING_SYSTEM "${CMAKE_HOST_SYSTEM}") # Windows 7, Linux-2.6.32, Darwin...
endif()
site_name(CTEST_SITE)
if(NOT DEFINED MITK_USE_QT)
set(MITK_USE_QT 1)
endif()
if(MITK_USE_QT)
if(NOT QT_QMAKE_EXECUTABLE)
find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4
HINTS ${QT_BINARY_DIR})
endif()
execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} --version
OUTPUT_VARIABLE MY_QT_VERSION
RESULT_VARIABLE qmake_error)
if(qmake_error)
message(FATAL_ERROR "Error when executing ${QT_QMAKE_EXECUTABLE} --version\n${qmake_error}")
endif()
string(REGEX REPLACE ".*Qt version ([0-9.]+) .*" "\\1" MY_QT_VERSION ${MY_QT_VERSION})
endif()
#
# Project specific properties
#
if(NOT CTEST_BUILD_NAME)
if(MITK_USE_QT)
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} Qt${MY_QT_VERSION} ${CTEST_BUILD_CONFIGURATION}")
else()
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} ${CTEST_BUILD_CONFIGURATION}")
endif()
endif()
set(PROJECT_BUILD_DIR "MITK-build")
set(CTEST_PATH "$ENV{PATH}")
if(WIN32)
set(ANN_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ANN-build/${CTEST_BUILD_CONFIGURATION}")
set(CPPUNIT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/CppUnit-build/${CTEST_BUILD_CONFIGURATION}")
set(GLUT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLUT-build/${CTEST_BUILD_CONFIGURATION}")
set(GLEW_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLEW-build/${CTEST_BUILD_CONFIGURATION}")
set(TINYXML_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/tinyxml-build/${CTEST_BUILD_CONFIGURATION}")
set(QWT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qwt-build/${CTEST_BUILD_CONFIGURATION}")
set(QXT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qxt-build/${CTEST_BUILD_CONFIGURATION}")
set(VTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/VTK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ACVD_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ACVD-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ITK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ITK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BOOST_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Boost-install/lib")
set(GDCM_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GDCM-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(OPENCV_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/OpenCV-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(POCO_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Poco-install/lib")
set(SOFA_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/SOFA-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BLUEBERRY_OSGI_DIR "${CTEST_BINARY_DIRECTORY}/MITK-build/bin/BlueBerry/org.blueberry.osgi/bin/${CTEST_BUILD_CONFIGURATION}")
set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}")
endif()
set(ENV{PATH} "${CTEST_PATH}")
set(SUPERBUILD_TARGETS "")
# If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here.
if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "")
set(GIT_REPOSITORY "http://git.mitk.org/MITK.git")
endif()
#
# Display build info
#
message("Site name: ${CTEST_SITE}")
message("Build name: ${CTEST_BUILD_NAME}")
message("Script Mode: ${SCRIPT_MODE}")
message("Coverage: ${WITH_COVERAGE}, MemCheck: ${WITH_MEMCHECK}")
#
# Set initial cache options
#
if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
set(CTEST_USE_LAUNCHERS 1)
set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} 1)
endif()
# Remove this if block after all dartclients work
if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION)
message(WARNING "Rename ADDITIONNAL to ADDITIONAL in your dartlclient script: ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION})
endif()
if(NOT DEFINED MITK_USE_ACVD)
set(MITK_USE_ACVD 1)
endif()
if(NOT DEFINED MITK_USE_Boost)
set(MITK_USE_Boost 1)
endif()
if(NOT DEFINED MITK_USE_OpenCV)
set(MITK_USE_OpenCV 1)
endif()
if(NOT DEFINED MITK_USE_Poco)
set(MITK_USE_Poco 1)
endif()
if(NOT DEFINED MITK_USE_SOFA)
set(MITK_USE_SOFA 1)
endif()
if(NOT DEFINED MITK_BUILD_ALL_APPS)
set(MITK_BUILD_ALL_APPS TRUE)
endif()
if(NOT DEFINED BLUEBERRY_BUILD_ALL_PLUGINS)
set(BLUEBERRY_BUILD_ALL_PLUGINS TRUE)
endif()
if(NOT DEFINED MITK_BUILD_ALL_PLUGINS)
set(MITK_BUILD_ALL_PLUGINS TRUE)
endif()
if(NOT DEFINED MITK_BUILD_EXAMPLES)
set(MITK_BUILD_EXAMPLES TRUE)
endif()
+if(NOT DEFINED MITK_USE_Python)
+ set(MITK_USE_Python TRUE)
+endif()
+
if(NOT BUILD_DiffusionMiniApps)
set(BUILD_DiffusionMiniApps TRUE)
endif()
set(INITIAL_CMAKECACHE_OPTIONS "
BLUEBERRY_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
MITK_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
MITK_BUILD_ALL_APPS:BOOL=${MITK_BUILD_ALL_APPS}
MITK_BUILD_EXAMPLES:BOOL=${MITK_BUILD_EXAMPLES}
SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE
MITK_USE_ACVD:BOOL=${MITK_USE_ACVD}
MITK_USE_Boost:BOOL=${MITK_USE_Boost}
MITK_USE_OpenCV:BOOL=${MITK_USE_OpenCV}
MITK_USE_Poco:BOOL=${MITK_USE_Poco}
MITK_USE_SOFA:BOOL=${MITK_USE_SOFA}
MITK_USE_QT:BOOL=${MITK_USE_QT}
${ADDITIONAL_CMAKECACHE_OPTION}
")
if(MITK_USE_QT)
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
endif()
# Write a cache file for populating the MITK initial cache (not the superbuild cache).
# This can be used to provide variables which are not passed through the
# superbuild process to the MITK configure step)
if(MITK_INITIAL_CACHE)
set(mitk_cache_file "${CTEST_SCRIPT_DIRECTORY}/mitk_initial_cache.txt")
file(WRITE "${mitk_cache_file}" "${MITK_INITIAL_CACHE}")
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
MITK_INITIAL_CACHE_FILE:INTERNAL=${mitk_cache_file}
")
endif()
#
# Download and include dashboard driver script
#
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/MITKDashboardDriverScript.cmake;hb=${hb}")
set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver)
downloadFile("${url}" "${dest}")
include(${dest})
diff --git a/CMake/PackageDepends/MITK_Numpy_Config.cmake b/CMake/PackageDepends/MITK_Numpy_Config.cmake
new file mode 100644
index 0000000000..d10c0eaa78
--- /dev/null
+++ b/CMake/PackageDepends/MITK_Numpy_Config.cmake
@@ -0,0 +1,4 @@
+if(MITK_USE_Python)
+ find_package(Numpy REQUIRED)
+ list(APPEND ALL_INCLUDE_DIRECTORIES ${NUMPY_INCLUDE_DIR})
+endif()
diff --git a/CMake/PackageDepends/MITK_SimpleITK_Config.cmake b/CMake/PackageDepends/MITK_SimpleITK_Config.cmake
new file mode 100644
index 0000000000..5c1925b95a
--- /dev/null
+++ b/CMake/PackageDepends/MITK_SimpleITK_Config.cmake
@@ -0,0 +1,4 @@
+find_package(SimpleITK REQUIRED CONFIG)
+list(APPEND ALL_INCLUDE_DIRECTORIES ${SimpleITK_INCLUDE_DIRS})
+list(APPEND ALL_LIBRARIES ${SimpleITK_LIBRARIES})
+link_directories(${SimpleITK_LIBRARY_DIRS})
diff --git a/CMake/mitkFunctionExternalPythonBuildStep.cmake b/CMake/mitkFunctionExternalPythonBuildStep.cmake
new file mode 100644
index 0000000000..0a6f55570d
--- /dev/null
+++ b/CMake/mitkFunctionExternalPythonBuildStep.cmake
@@ -0,0 +1,39 @@
+#! CMake function that runs a python build step from a setup.py script,
+#! e.g. python setup.py build. This is used to build external python
+#! libraries like numpy. The function takes the necessary build steps,
+#! python executable etc. as arguments. The specific build command executed
+#! by the runtime is passed as ARGN.
+#!
+#! params:
+#! proj - The name of the project
+#! step - Buildstep used to label the generated outputs, e.g. configure;build;install
+#! _python_executable - The python executable
+#! _bin_dir - The current binary from where commands are executed relative to it
+#! ARGN - Python command that will be run in the _bin_dir/proj-src folder
+#! e.g. setup.py build --someflags
+#!
+function(mitkFunctionExternalPythonBuildStep proj step _python_executable _bin_dir)
+
+ # the specific python build command run by this step
+ set(_command ${ARGN})
+
+ message("Running ${proj} ${step}:${PYTHON_EXECUTABLE} ${_command}")
+
+ execute_process(
+ COMMAND ${_python_executable} ${_command}
+ WORKING_DIRECTORY ${_bin_dir}/${proj}-src
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE error
+ )
+ set(output_file "${_bin_dir}/${proj}-cmake/${proj}_${step}_step_output.txt")
+ file(WRITE ${output_file} ${output})
+
+ set(error_file "${_bin_dir}/${proj}-cmake/${proj}_${step}_step_error.txt")
+ file(WRITE ${error_file} ${error})
+
+ if(NOT ${result} EQUAL 0)
+ message(FATAL_ERROR "Error in: ${proj}: ${error}")
+ endif()
+endfunction()
+
diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
index 6b3c31fb2f..fa721ede9c 100644
--- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake
+++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
@@ -1,165 +1,175 @@
function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir)
set(_dir_candidates ${MITK_VTK_LIBRARY_DIRS} ${MITK_ITK_LIBRARY_DIRS}
"${MITK_BINARY_DIR}/bin" "${MITK_BINARY_DIR}/bin/plugins")
# Determine the Qt4/5 library installation prefix
set(_qmake_location )
if(MITK_USE_Qt4)
set(_qmake_location ${QT_QMAKE_EXECUTABLE})
elseif(MITK_USE_Qt5 AND TARGET ${Qt5Core_QMAKE_EXECUTABLE})
get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE}
PROPERTY IMPORT_LOCATION)
endif()
if(_qmake_location)
if(NOT _qt_install_libs)
if(WIN32)
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs)
set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE)
endif()
if(_qt_install_libs)
list(APPEND _dir_candidates ${_qt_install_libs})
endif()
elseif(MITK_USE_QT)
message(WARNING "The qmake executable could not be found.")
endif()
get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
if(_additional_paths)
list(APPEND _dir_candidates ${_additional_paths})
endif()
if(VTK_DIR)
find_package(VTK QUIET)
if(VTK_RUNTIME_LIBRARY_DIRS)
list(APPEND _dir_candidates ${VTK_RUNTIME_LIBRARY_DIRS})
endif()
endif()
# The code below is sub-optimal. It makes assumptions about
# the structure of the build directories, pointed to by
# the *_DIR variables. Instead, we should rely on package
# specific "LIBRARY_DIRS" variables, if they exist.
if(WIN32)
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/bin")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/bin")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/bin")
+ if(Python_DIR)
+ list(APPEND _dir_candidates "${Python_DIR}/bin")
+ endif()
+ if(SimpleITK_DIR)
+ list(APPEND _dir_candidates "${SimpleITK_DIR}/bin")
endif()
list(APPEND _dir_candidates "${ITK_DIR}/bin")
else()
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/lib")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/lib")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/lib")
+ if(Python_DIR)
+ list(APPEND _dir_candidates "${Python_DIR}/lib")
+ endif()
+ if(SimpleITK_DIR)
+ list(APPEND _dir_candidates "${SimpleITK_DIR}/lib")
endif()
list(APPEND _dir_candidates "${ITK_DIR}/lib")
endif()
if(MITK_USE_Python AND CTK_PYTHONQT_INSTALL_DIR)
list(APPEND _dir_candidates "${CTK_PYTHONQT_INSTALL_DIR}/bin")
endif()
if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost)
list(APPEND _dir_candidates "${Boost_LIBRARY_DIR}")
endif()
if(ACVD_DIR)
list(APPEND _dir_candidates "${ACVD_DIR}/bin")
endif()
if(ANN_DIR)
list(APPEND _dir_candidates "${ANN_DIR}")
endif()
if(CppUnit_DIR)
list(APPEND _dir_candidates "${CppUnit_DIR}")
endif()
if(GLUT_DIR)
list(APPEND _dir_candidates "${GLUT_DIR}")
endif()
if(GDCM_DIR)
list(APPEND _dir_candidates "${GDCM_DIR}/bin")
endif()
if(GLEW_DIR)
list(APPEND _dir_candidates "${GLEW_DIR}")
endif()
if(tinyxml_DIR)
list(APPEND _dir_candidates "${tinyxml_DIR}")
endif()
if(Poco_DIR)
list(APPEND _dir_candidates "${Poco_DIR}/lib")
endif()
if(Qwt_DIR)
list(APPEND _dir_candidates "${Qwt_DIR}")
endif()
if(Qxt_DIR)
list(APPEND _dir_candidates "${Qxt_DIR}")
endif()
if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD)
list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin")
endif()
if(MITK_USE_CTK)
list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}")
foreach(_ctk_library ${CTK_LIBRARIES})
if(${_ctk_library}_LIBRARY_DIRS)
list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}")
endif()
endforeach()
endif()
if(MITK_USE_BLUEBERRY)
if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY)
if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
else()
list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
endif()
endif()
endif()
if(MITK_LIBRARY_DIRS)
list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS})
endif()
list(REMOVE_DUPLICATES _dir_candidates)
set(_search_dirs )
foreach(_dir ${_dir_candidates})
if(EXISTS "${_dir}/${intermediate_dir}")
list(APPEND _search_dirs "${_dir}/${intermediate_dir}")
else()
list(APPEND _search_dirs "${_dir}")
endif()
endforeach()
# Special handling for "internal" search dirs. The intermediate directory
# might not have been created yet, so we can't check for its existence.
# Hence we just add it for Windows without checking.
set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins")
if(WIN32)
foreach(_dir ${_internal_search_dirs})
set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs})
endforeach()
else()
set(_search_dirs ${_internal_search_dirs} ${_search_dirs})
endif()
list(REMOVE_DUPLICATES _search_dirs)
set(${search_path} ${_search_dirs} PARENT_SCOPE)
endfunction()
diff --git a/CMake/mitkFunctionInstallPython.cmake b/CMake/mitkFunctionInstallPython.cmake
new file mode 100644
index 0000000000..d8ea8a74f5
--- /dev/null
+++ b/CMake/mitkFunctionInstallPython.cmake
@@ -0,0 +1,156 @@
+#! This CMake macro installs the python runtime with
+#! all python related libraries and toolkits. Py files are
+#! searched one by one with a globbing expression to generate a list used
+#! by the mac and NSIS installer.
+#!
+#! params:
+#! _python_libs Returns a list of the installed libraries. Used to fixup the bundle.
+#! _python_dirs Returns a list with the directories containig the dependencies
+#! to the installed libs.
+#! _app_bundle App bundle name in case of a Apple bundle.
+#!
+function(mitkFunctionInstallPython _python_libs_out _python_dirs_out _app_bundle)
+
+ # find package sets the python version numbers
+ find_package(PythonLibs REQUIRED)
+ find_package(PythonInterp REQUIRED)
+
+ set(_python_libs )
+ set(_python_dirs )
+ # set the destination bundle
+ set(_destination bin)
+ if(APPLE)
+ set(_destination ${_app_bundle})
+ endif()
+
+ if(UNIX)
+ # apple and linux only supports .so as loadable extension
+ set(PYTHON_LIB_SUFFIX .so)
+ set(_py_include_postfix python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/)
+ set(_python_runtime_dir lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})
+ else(WIN32)
+ # windows only supports pyd as loadable extension
+ set(PYTHON_LIB_SUFFIX .pyd)
+ set(_py_include_postfix )
+ set(_python_runtime_dir Lib)
+ endif()
+
+ # install OpenCV python wrapping
+ if(MITK_USE_OpenCV)
+ list(APPEND _python_libs "cv2${PYTHON_LIB_SUFFIX}")
+
+ if(UNIX)
+ install(FILES "${OpenCV_DIR}/lib/cv2${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+ else()
+ install(FILES "${OpenCV_DIR}/lib/Release/cv2${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+ endif()
+
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/cv2${CMAKE_SHARED_LIBRARY_SUFFIX}\")")
+ endif()
+
+ list(APPEND _python_dirs "${OpenCV_DIR}/lib")
+ endif()
+
+ # install VTK python wrapping
+ find_package(VTK REQUIRED)
+
+ set(_VTK_PYTHON_TARGETS )
+
+ # find all vtk python wrapped targets
+ foreach(_lib ${VTK_LIBRARIES})
+ # exclude system libs
+ if(${_lib} MATCHES "^vtk.+")
+ # use only python wrapped modules ( targets end with PythonD )
+ if(TARGET ${_lib}PythonD)
+ list(APPEND _VTK_PYTHON_TARGETS ${_lib}Python)
+ endif()
+ endif()
+ endforeach()
+
+ # install the python modules and loaders
+ foreach(_target ${_VTK_PYTHON_TARGETS})
+ # get the properties of the python wrapped target
+ if( CMAKE_BUILD_TYPE STREQUAL "Debug")
+ get_target_property(_target_lib "${_target}D" IMPORTED_LOCATION_DEBUG)
+ else()
+ get_target_property(_target_lib "${_target}D" IMPORTED_LOCATION_RELEASE)
+ endif()
+ get_filename_component(_filepath "${_target_lib}" PATH)
+
+ install(FILES "${_filepath}/${_target}${PYTHON_LIB_SUFFIX}" DESTINATION ${_destination})
+
+ if(UNIX AND NOT APPLE )
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/${_target}${PYTHON_LIB_SUFFIX}\")")
+ endif()
+ list(APPEND _python_libs "${_target}${PYTHON_LIB_SUFFIX}")
+ endforeach()
+
+ # install vtk python. This folder contains all *.py and
+ # *.pyc files for VTK module loading.
+ # glob through all files, NSIS can't use directories
+ file(GLOB_RECURSE item RELATIVE "${VTK_DIR}/Wrapping/Python/vtk" "${VTK_DIR}/Wrapping/Python/vtk/*.py*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${VTK_DIR}/Wrapping/Python/vtk/${f}" DESTINATION ${_destination}/Python/vtk/${_filepath})
+ endforeach()
+
+ list(APPEND _python_dirs "${VTK_DIR}/lib")
+
+ # install the python runtime from the superbuild
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ if(UNIX)
+ list(APPEND _python_dirs "${Python_DIR}/lib")
+ else() #WIN32
+ list(APPEND _python_dirs "${Python_DIR}/libs")
+ list(APPEND _python_dirs "${Python_DIR}/bin")
+ endif()
+
+ file(GLOB_RECURSE item RELATIVE "${Python_DIR}/${_python_runtime_dir}" "${Python_DIR}/${_python_runtime_dir}/*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${Python_DIR}/${_python_runtime_dir}/${f}" DESTINATION ${_destination}/Python/${_python_runtime_dir}/${_filepath})
+ endforeach()
+
+ # config will by read out at runtime
+ install(FILES "${Python_DIR}/include/${_py_include_postfix}pyconfig.h" DESTINATION ${_destination}/Python/include/${_py_include_postfix})
+
+ # add simple itk python wrapping file to the dependency list to resolve linked libraries
+ file(GLOB_RECURSE item RELATIVE "${Python_DIR}/${_python_runtime_dir}" "${Python_DIR}/${_python_runtime_dir}/_SimpleITK${PYTHON_LIB_SUFFIX}")
+ foreach(f ${item})
+ list(APPEND _python_libs "Python/${_python_runtime_dir}/${f}")
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/Python/${_python_runtime_dir}/${f}\")")
+ endif()
+ endforeach()
+ else()
+ # Deploy the SimpleITK egg into the MITK installer
+ set(_sitk_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/${_python_runtime_dir}/site-packages)
+
+ # install everything in the userbase into Python/SimpleITK
+ file(GLOB_RECURSE item RELATIVE "${_sitk_userbase_install}" "${_sitk_userbase_install}/*")
+ foreach(f ${item})
+ get_filename_component(_filepath "${f}" PATH)
+ install(FILES "${_sitk_userbase_install}/${f}" DESTINATION ${_destination}/Python/SimpleITK/${_filepath})
+ endforeach()
+
+ # find and add the _SimpleITK library to the dependencies
+ file(GLOB_RECURSE item RELATIVE "${_sitk_userbase_install}" "${_sitk_userbase_install}/_SimpleITK${PYTHON_LIB_SUFFIX}")
+ foreach(f ${item})
+ list(APPEND _python_libs "Python/SimpleITK/${f}")
+ if(UNIX AND NOT APPLE)
+ install(CODE "file(RPATH_REMOVE
+ FILE \"\${CMAKE_INSTALL_PREFIX}/bin/Python/SimpleITK/${f}\")")
+ endif()
+ endforeach()
+ endif()
+
+ list(REMOVE_DUPLICATES _python_dirs)
+
+ set(${_python_libs_out} ${_python_libs} PARENT_SCOPE)
+ set(${_python_dirs_out} ${_python_dirs} PARENT_SCOPE)
+endfunction()
+
diff --git a/CMake/mitkMacroInstall.cmake b/CMake/mitkMacroInstall.cmake
index 5efadc76c3..8385998d6b 100644
--- a/CMake/mitkMacroInstall.cmake
+++ b/CMake/mitkMacroInstall.cmake
@@ -1,177 +1,192 @@
#
# MITK specific install macro
#
# On Mac everything is installed for each bundle listed in MACOSX_BUNDLE_NAMES
# by replacing the DESTINATION parameter. Everything else is passed to the CMake INSTALL command
#
# Usage: MITK_INSTALL( )
#
macro(MITK_INSTALL)
set(ARGS ${ARGN})
set(install_directories "")
list(FIND ARGS DESTINATION _destination_index)
# set(_install_DESTINATION "")
if(_destination_index GREATER -1)
message(SEND_ERROR "MITK_INSTALL macro must not be called with a DESTINATION parameter.")
### This code was a try to replace a given DESTINATION
#math(EXPR _destination_index ${_destination_index} + 1)
#list(GET ARGS ${_destination_index} _install_DESTINATION)
#string(REGEX REPLACE ^bin "" _install_DESTINATION ${_install_DESTINATION})
else()
if(NOT MACOSX_BUNDLE_NAMES)
install(${ARGS} DESTINATION bin)
else()
foreach(bundle_name ${MACOSX_BUNDLE_NAMES})
install(${ARGS} DESTINATION ${bundle_name}.app/Contents/MacOS/${_install_DESTINATION})
endforeach()
endif()
endif()
endmacro()
# Fix _target_location
# This is used in several install macros
macro(_fixup_target)
if(NOT intermediate_dir)
if(WIN32 AND NOT MINGW)
set(intermediate_dir Release)
else()
set(intermediate_dir .)
endif()
endif()
+ set(_python_libs )
+ set(_python_dirs )
+ if(MITK_USE_Python)
+ include(mitkFunctionInstallPython)
+ mitkFunctionInstallPython(_python_libs _python_dirs "${_bundle_dest_dir}")
+ endif()
+
mitkFunctionGetLibrarySearchPaths(_search_paths ${intermediate_dir})
install(CODE "
set(_bundle_dest_dir \"${_bundle_dest_dir}\")
if(_bundle_dest_dir)
set(_bin_path \"\${CMAKE_INSTALL_PREFIX}/\${_bundle_dest_dir}\")
else()
set(_bin_path \"\${CMAKE_INSTALL_PREFIX}/bin\")
endif()
macro(gp_item_default_embedded_path_override item default_embedded_path_var)
get_filename_component(_item_name \"\${item}\" NAME)
get_filename_component(_item_path \"\${item}\" PATH)
# We have to fix all path references to build trees for plugins
if(NOT _item_path MATCHES \"\${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}\")
# item with relative path or embedded path pointing to some build dir
set(full_path \"full_path-NOTFOUND\")
file(GLOB_RECURSE full_path \${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}/\${_item_name} )
list(LENGTH full_path full_path_length)
if(full_path_length GREATER 1)
list(GET full_path 0 full_path)
endif()
get_filename_component(_item_path \"\${full_path}\" PATH)
endif()
set(_plugins_path \"\${_bin_path}/plugins\")
if(_item_path STREQUAL _plugins_path
OR (_item_path MATCHES \"\${_plugins_path}/\" AND _item_name MATCHES \"liborg\") # this is for legacy BlueBerry bundle support
)
# Only fix plugins
message(\"override: \${item}\")
message(\"found file: \${_item_path}/\${_item_name}\")
if(APPLE)
string(REPLACE
\${CMAKE_INSTALL_PREFIX}/${_bundle_dest_dir}
@executable_path \${default_embedded_path_var} \"\${_item_path}\" )
else()
set(\${default_embedded_path_var} \"\${_item_path}\")
endif()
message(\"override result: \${\${default_embedded_path_var}}\")
endif()
endmacro(gp_item_default_embedded_path_override)
macro(gp_resolved_file_type_override file type)
if(NOT APPLE)
get_filename_component(_file_path \"\${file}\" PATH)
get_filename_component(_file_name \"\${file}\" NAME)
if(_file_path MATCHES \"^\${CMAKE_INSTALL_PREFIX}\")
set(\${type} \"local\")
endif()
if(_file_name MATCHES gdiplus)
set(\${type} \"system\")
endif(_file_name MATCHES gdiplus)
endif()
endmacro(gp_resolved_file_type_override)
if(NOT APPLE)
macro(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
if(\${item} MATCHES \"blueberry_osgi\")
get_filename_component(_item_name \${item} NAME)
set(\${resolved_item_var} \"\${exepath}/plugins/\${_item_name}\")
set(\${resolved_var} 1)
endif()
endmacro()
endif()
if(\"${_install_GLOB_PLUGINS}\" STREQUAL \"TRUE\")
set(GLOBBED_PLUGINS )
set(_bb_osgi_lib \"\${_bin_path}/liborg_blueberry_osgi${CMAKE_SHARED_LIBRARY_SUFFIX}\")
if(EXISTS \"\${_bb_osgi_lib}\")
list(APPEND GLOBBED_PLUGINS \"\${_bb_osgi_lib}\")
endif()
# Iterate over all sub-directories which contain plug-ins
# (BlueBerry plug-ins, Qt plug-ins, and auto-load modules)
file(GLOB _children \"\${_bin_path}/*\")
foreach(_child \${_children})
if(IS_DIRECTORY \${_child})
set(_plugins )
set(_modules )
file(GLOB_RECURSE _plugins \"\${_child}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
if(_plugins)
list(APPEND GLOBBED_PLUGINS \${_plugins})
endif()
# Now glob for all modules which might have a different extensions.
# E.g. on MacOS plugins could have a .dylib extension as well as a .so extension
if(NOT \"${CMAKE_SHARED_MODULE_SUFFIX}\" STREQUAL \"\" AND NOT \"${CMAKE_SHARED_MODULE_SUFFIX}\" STREQUAL \"${CMAKE_SHARED_LIBRARY_SUFFIX}\")
file(GLOB_RECURSE _modules \"\${_child}/*${CMAKE_SHARED_MODULE_SUFFIX}\")
endif()
if(_modules)
list(APPEND GLOBBED_PLUGINS \${_modules})
endif()
endif()
endforeach()
endif()
set(PLUGINS )
foreach(_plugin ${_install_PLUGINS} \${GLOBBED_PLUGINS})
get_filename_component(_plugin_realpath \${_plugin} REALPATH)
list(APPEND PLUGINS \${_plugin_realpath})
endforeach()
+ foreach(_py_lib ${_python_libs})
+ list(APPEND PLUGINS \"\${_bin_path}/\${_py_lib}\")
+ endforeach()
+
if(PLUGINS)
list(REMOVE_DUPLICATES PLUGINS)
endif(PLUGINS)
message(\"globbed plugins: \${PLUGINS}\")
set(CMAKE_MODULE_PATH ${MITK_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} )
set(DIRS \"${_search_paths}\")
set(_additional_search_paths ${_install_LIBRARY_DIRS})
if(_additional_search_paths)
set(DIRS \"\${DIRS};\${_additional_search_paths}\")
endif()
foreach(_plugin \${PLUGINS})
get_filename_component(_pluginpath \${_plugin} PATH)
list(APPEND DIRS \"\${_pluginpath}\")
endforeach(_plugin)
+ foreach(_dir ${_python_dirs})
+ list(APPEND DIRS \"\${_dir}\")
+ endforeach()
+
list(REMOVE_DUPLICATES DIRS)
# use custom version of BundleUtilities
include(BundleUtilities)
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/${_target_location}\" \"\${PLUGINS}\" \"\${DIRS}\")
")
endmacro()
diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake
index 81d35de915..14bd3c0c93 100644
--- a/CMakeExternals/CTK.cmake
+++ b/CMakeExternals/CTK.cmake
@@ -1,95 +1,98 @@
#-----------------------------------------------------------------------------
# CTK
#-----------------------------------------------------------------------------
if(MITK_USE_CTK)
# Sanity checks
if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR})
message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj CTK)
set(proj_DEPENDENCIES )
set(CTK_DEPENDS ${proj})
if(NOT DEFINED CTK_DIR)
set(revision_tag fd3ecf96)
#IF(${proj}_REVISION_TAG)
# SET(revision_tag ${${proj}_REVISION_TAG})
#ENDIF()
set(ctk_optional_cache_args )
if(MITK_USE_Python)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=ON
-DCTK_ENABLE_Python_Wrapping:BOOL=ON
-DCTK_APP_ctkSimplePythonShell:BOOL=ON
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
)
else()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF
-DCTK_ENABLE_Python_Wrapping:BOOL=OFF
-DCTK_APP_ctkSimplePythonShell:BOOL=OFF
)
endif()
if(MITK_USE_DCMTK)
list(APPEND ctk_optional_cache_args
-DDCMTK_DIR:PATH=${DCMTK_DIR}
)
list(APPEND proj_DEPENDENCIES DCMTK)
else()
list(APPEND ctk_optional_cache_args
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
)
endif()
FOREACH(type RUNTIME ARCHIVE LIBRARY)
IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY)
LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY})
ENDIF()
ENDFOREACH()
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz
URL_MD5 a33be5c622fee05179c55e67a7d1b9cf
UPDATE_COMMAND ""
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${ctk_optional_cache_args}
-DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION}
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
-DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON
-DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON
-DCTK_LIB_PluginFramework:BOOL=ON
-DCTK_LIB_DICOM/Widgets:BOOL=ON
-DCTK_LIB_XNAT/Core:BOOL=ON
-DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON
-DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON
-DCTK_USE_GIT_PROTOCOL:BOOL=OFF
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
-DqRestAPI_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/qRestAPI_5f3a03b1.tar.gz
DEPENDS ${proj_DEPENDENCIES}
)
set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/CableSwig.cmake b/CMakeExternals/CableSwig.cmake
deleted file mode 100644
index 73cc64f959..0000000000
--- a/CMakeExternals/CableSwig.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-#-----------------------------------------------------------------------------
-# CableSwig
-#-----------------------------------------------------------------------------
-
-if(MITK_USE_Python)
-
-# Sanity checks
-if(DEFINED CableSwig_DIR AND NOT EXISTS ${CableSwig_DIR})
- message(FATAL_ERROR "CableSwig_DIR variable is defined but corresponds to non-existing directory")
-endif()
-
-set(proj CableSwig)
-set(proj_DEPENDENCIES )
-set(CableSwig_DEPENDS ${proj})
-
-if(NOT DEFINED CableSwig_DIR)
-
- set(additional_cmake_args )
-
- ExternalProject_Add(${proj}
- SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
- BINARY_DIR ${proj}-build
- PREFIX ${proj}-cmake
- URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CableSwig-ITK-3.20.0-v2.tar.gz
- URL_MD5 893882bf8b4fbfbae3fe8c747a75f7a0
- INSTALL_COMMAND ""
- CMAKE_GENERATOR ${gen}
- CMAKE_ARGS
- ${ep_common_args}
- ${additional_cmake_args}
- -DBUILD_TESTING:BOOL=OFF
- -DSWIG_BUILD_EXAMPLES:BOOL=OFF
- DEPENDS ${proj_DEPENDENCIES}
- )
-
- set(CableSwig_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
-
-else()
-
- mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
-
-endif()
-
-endif()
diff --git a/CMakeExternals/ITK.cmake b/CMakeExternals/ITK.cmake
index 2dde71437d..779cfb7ec8 100644
--- a/CMakeExternals/ITK.cmake
+++ b/CMakeExternals/ITK.cmake
@@ -1,98 +1,72 @@
#-----------------------------------------------------------------------------
# ITK
#-----------------------------------------------------------------------------
# Sanity checks
if(DEFINED ITK_DIR AND NOT EXISTS ${ITK_DIR})
message(FATAL_ERROR "ITK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj ITK)
set(proj_DEPENDENCIES GDCM)
-if(MITK_USE_Python)
- list(APPEND proj_DEPENDENCIES CableSwig)
-endif()
+
if(MITK_USE_OpenCV)
list(APPEND proj_DEPENDENCIES OpenCV)
endif()
set(ITK_DEPENDS ${proj})
if(NOT DEFINED ITK_DIR)
set(additional_cmake_args )
if(MINGW)
set(additional_cmake_args
-DCMAKE_USE_WIN32_THREADS:BOOL=ON
-DCMAKE_USE_PTHREADS:BOOL=OFF)
endif()
- if(MITK_USE_Python)
-
- list(APPEND additional_cmake_args
- -DITK_WRAPPING:BOOL=ON
- -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
- -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
- -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
- -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- #-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
- #-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
- -DCableSwig_DIR:PATH=${CableSwig_DIR}
- #-DITK_WRAP_JAVA:BOOL=OFF
- -DITK_WRAP_unsigned_char:BOOL=ON
- #-DITK_WRAP_double:BOOL=ON
- -DITK_WRAP_rgb_unsigned_char:BOOL=ON
- #-DITK_WRAP_rgba_unsigned_char:BOOL=ON
- -DITK_WRAP_signed_char:BOOL=ON
- #-DWRAP_signed_long:BOOL=ON
- -DITK_WRAP_signed_short:BOOL=ON
- -DITK_WRAP_short:BOOL=ON
- -DITK_WRAP_unsigned_long:BOOL=ON
- )
- else()
- list(APPEND additional_cmake_args
- -DUSE_WRAP_ITK:BOOL=OFF
- )
- endif()
+ list(APPEND additional_cmake_args
+ -DUSE_WRAP_ITK:BOOL=OFF
+ )
if(MITK_USE_OpenCV)
list(APPEND additional_cmake_args
-DModule_ITKVideoBridgeOpenCV:BOOL=ON
-DOpenCV_DIR:PATH=${OpenCV_DIR}
)
endif()
# Keep the behaviour of ITK 4.3 which by default turned on ITK Review
# see MITK bug #17338
list(APPEND additional_cmake_args
-DModule_ITKReview:BOOL=ON
)
set(ITK_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchITK-4.5.1.cmake)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/InsightToolkit-4.5.1-3e550bf8.tar.gz
URL_MD5 80e433ffc0e81cdc19a03dd02a3c329b
INSTALL_COMMAND ""
PATCH_COMMAND ${ITK_PATCH_COMMAND}
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${additional_cmake_args}
-DBUILD_TESTING:BOOL=OFF
-DBUILD_EXAMPLES:BOOL=OFF
-DITK_USE_SYSTEM_GDCM:BOOL=ON
-DGDCM_DIR:PATH=${GDCM_DIR}
DEPENDS ${proj_DEPENDENCIES}
)
set(ITK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
diff --git a/CMakeExternals/Numpy.cmake b/CMakeExternals/Numpy.cmake
new file mode 100644
index 0000000000..03121b31a1
--- /dev/null
+++ b/CMakeExternals/Numpy.cmake
@@ -0,0 +1,88 @@
+#-----------------------------------------------------------------------------
+# Numpy
+#-----------------------------------------------------------------------------
+if( MITK_USE_Python AND NOT MITK_USE_SYSTEM_PYTHON )
+ # Sanity checks
+ if(DEFINED Numpy_DIR AND NOT EXISTS ${Numpy_DIR})
+ message(FATAL_ERROR "Numpy_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if( NOT DEFINED Numpy_DIR )
+ set(proj Numpy)
+ set(${proj}_DEPENDENCIES Python)
+ set(Numpy_DEPENDS ${proj})
+
+ # setup build environment and disable fortran, blas and lapack
+ set(_numpy_env
+ "
+ set(ENV{F77} \"\")
+ set(ENV{F90} \"\")
+ set(ENV{FFLAGS} \"\")
+ set(ENV{ATLAS} \"None\")
+ set(ENV{BLAS} \"None\")
+ set(ENV{LAPACK} \"None\")
+ set(ENV{MKL} \"None\")
+ set(ENV{VS_UNICODE_OUTPUT} \"\")
+ set(ENV{CC} \"${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}\")
+ set(ENV{CFLAGS} \"${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}\")
+ set(ENV{CXX} \"${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}\")
+ set(ENV{CXXFLAGS} \"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}\")
+ set(ENV{LDFLAGS} \"${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}\")
+
+ ")
+
+ set(_numpy_build_step ${MITK_SOURCE_DIR}/CMake/mitkFunctionExternalPythonBuildStep.cmake)
+
+ set(_configure_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_configure_step.cmake)
+ file(WRITE ${_configure_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ file(WRITE \"${CMAKE_BINARY_DIR}/${proj}-src/site.cfg\" \"\")
+ mitkFunctionExternalPythonBuildStep(${proj} configure ${PYTHON_EXECUTABLE} \"${CMAKE_BINARY_DIR}\" setup.py config)
+ ")
+
+ # build step
+ set(_build_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_build_step.cmake)
+ file(WRITE ${_build_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ mitkFunctionExternalPythonBuildStep(${proj} build ${PYTHON_EXECUTABLE} \"${CMAKE_BINARY_DIR}\" setup.py build --fcompiler=none)
+ ")
+
+ # install step
+ set(_install_dir ${Python_DIR})
+ if(WIN32)
+ STRING(REPLACE "/" "\\\\" _install_dir ${Python_DIR})
+ endif()
+
+ set(_install_step ${CMAKE_BINARY_DIR}/${proj}-cmake/${proj}_install_step.cmake)
+ file(WRITE ${_install_step}
+ "${_numpy_env}
+ include(\"${_numpy_build_step}\")
+ mitkFunctionExternalPythonBuildStep(${proj} install ${PYTHON_EXECUTABLE} \"${CMAKE_BINARY_DIR}\" setup.py install --prefix=${_install_dir})
+ ")
+
+ set(Numpy_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/numpy-1.4.1.tar.gz)
+ set(Numpy_MD5 "5c7b5349dc3161763f7f366ceb96516b")
+
+ ExternalProject_Add(${proj}
+ URL ${Numpy_URL}
+ URL_MD5 ${Numpy_MD5}
+ SOURCE_DIR ${proj}-src
+ PREFIX ${proj}-cmake
+ BUILD_IN_SOURCE 1
+ CONFIGURE_COMMAND ${CMAKE_COMMAND} -P ${_configure_step}
+ BUILD_COMMAND ${CMAKE_COMMAND} -P ${_build_step}
+ INSTALL_COMMAND ${CMAKE_COMMAND} -P ${_install_step}
+
+ DEPENDS
+ ${${proj}_DEPENDENCIES}
+ )
+
+ set(Numpy_DIR ${MITK_PYTHON_SITE_DIR}/numpy)
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeExternals/OpenCV.cmake b/CMakeExternals/OpenCV.cmake
index 6df5c6522c..77dd1d3942 100644
--- a/CMakeExternals/OpenCV.cmake
+++ b/CMakeExternals/OpenCV.cmake
@@ -1,92 +1,97 @@
#-----------------------------------------------------------------------------
# OpenCV
#-----------------------------------------------------------------------------
if(MITK_USE_OpenCV)
# Sanity checks
if(DEFINED OpenCV_DIR AND NOT EXISTS ${OpenCV_DIR})
message(FATAL_ERROR "OpenCV_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj OpenCV)
set(proj_DEPENDENCIES)
set(OpenCV_DEPENDS ${proj})
if(NOT DEFINED OpenCV_DIR)
set(additional_cmake_args
-DBUILD_opencv_java:BOOL=OFF
-DBUILD_opencv_ts:BOOL=OFF
-DBUILD_PERF_TESTS:BOOL=OFF
)
if(MITK_USE_Python)
#message(STATUS "PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}")
#message(STATUS "PYTHON_DEBUG_LIBRARY: ${PYTHON_DEBUG_LIBRARY}")
#message(STATUS "PYTHON_INCLUDE_DIR: ${PYTHON_INCLUDE_DIR}")
#message(STATUS "PYTHON_LIBRARY: ${PYTHON_LIBRARY}")
-
list(APPEND additional_cmake_args
-DBUILD_opencv_python:BOOL=ON
-DBUILD_NEW_PYTHON_SUPPORT:BOOL=ON
-DPYTHON_DEBUG_LIBRARY:FILEPATH=${PYTHON_DEBUG_LIBRARY}
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
+
#-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
#-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python Numpy)
+ # export python home
+ set(ENV{PYTHONHOME} "${Python_DIR}")
+ endif()
else()
list(APPEND additional_cmake_args
-DBUILD_opencv_python:BOOL=OFF
-DBUILD_NEW_PYTHON_SUPPORT:BOOL=OFF
)
endif()
# 12-05-02, muellerm, added QT usage by OpenCV if QT is used in MITK
# 12-09-11, muellerm, removed automatic usage again, since this will struggle with the MITK Qt application object
if(MITK_USE_QT)
list(APPEND additional_cmake_args
-DWITH_QT:BOOL=OFF
-DWITH_QT_OPENGL:BOOL=OFF
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
)
endif()
set(OpenCV_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchOpenCV-2.4.8.2.cmake)
set(opencv_url ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/OpenCV-2.4.8.2.tar.gz)
set(opencv_url_md5 07fa7c1d225ea7fe8eeb1270a6b00e69)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${opencv_url}
URL_MD5 ${opencv_url_md5}
INSTALL_COMMAND ""
PATCH_COMMAND ${OpenCV_PATCH_COMMAND}
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
-DBUILD_DOCS:BOOL=OFF
-DBUILD_TESTS:BOOL=OFF
-DBUILD_EXAMPLES:BOOL=OFF
-DBUILD_DOXYGEN_DOCS:BOOL=OFF
-DWITH_CUDA:BOOL=ON
${additional_cmake_args}
DEPENDS ${proj_DEPENDENCIES}
)
set(OpenCV_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/PCRE.cmake b/CMakeExternals/PCRE.cmake
new file mode 100644
index 0000000000..6b2dc67d1d
--- /dev/null
+++ b/CMakeExternals/PCRE.cmake
@@ -0,0 +1,35 @@
+#--------------------------------------------------------------------------
+# PCRE (Perl Compatible Regular Expressions)
+#--------------------------------------------------------------------------
+if(MITK_USE_PCRE)
+ if(DEFINED PCRE_DIR AND NOT EXISTS ${PCRE_DIR})
+ message(FATAL_ERROR "PCRE_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+ if(NOT PCRE_DIR)
+
+ set(proj PCRE)
+ set(${proj}_DEPENDENCIES "")
+ set(PCRE_TARGET_VERSION 8.35)
+
+ ExternalProject_add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/pcre-8.35.tar.gz
+ URL_MD5 "ed58bcbe54d3b1d59e9f5415ef45ce1c"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build
+ INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ PREFIX ${proj}-cmake
+ CONFIGURE_COMMAND /./configure
+ CC=${CMAKE_C_COMPILER}${CMAKE_C_COMPILER_ARG1}
+ LDFLAGS=${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}
+ CXX=${CMAKE_CXX_COMPILER}${CMAKE_CXX_COMPILER_ARG1}
+ --prefix=
+ --disable-shared
+ DEPENDS "${${proj}_DEPENDENCIES}"
+ )
+
+ set(PCRE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install)
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${${proj}_DEPENDENCIES}")
+ endif()
+endif()
diff --git a/CMakeExternals/PatchPython.cmake b/CMakeExternals/PatchPython.cmake
new file mode 100644
index 0000000000..a9e3587124
--- /dev/null
+++ b/CMakeExternals/PatchPython.cmake
@@ -0,0 +1,8 @@
+#
+# Windows python 2.7.3 patches for the CMake build system
+# https://github.com/davidsansome/python-cmake-buildsystem/tree/master/cmake/patches-win32
+#
+set(in ${CMAKE_CURRENT_LIST_DIR}/msvc9compiler.py.patched)
+set(out ${PYTHON_SOURCE_DIR}/Lib/distutils/msvc9compiler.py)
+
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${in} ${out})
diff --git a/CMakeExternals/PatchSimpleITK.cmake b/CMakeExternals/PatchSimpleITK.cmake
new file mode 100644
index 0000000000..185fad393d
--- /dev/null
+++ b/CMakeExternals/PatchSimpleITK.cmake
@@ -0,0 +1,18 @@
+# Called by ITK.cmake (ExternalProject_Add) as a patch for ITK to work with external GDCM 2.2.1
+# and remove all itk video libs to resolve external windows linker errors with opencv
+
+set(path "CMakeLists.txt")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "ITK_LIBRARY_DIRS}\")" "ITK_LIBRARY_DIRS}\" \"\${GDCM_DIR}/bin\")
+ list(REMOVE_ITEM ITK_LIBRARIES ITKVideoBridgeOpenCV ITKVideoCore ITKVideoIO)" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
+
+# fix for double import targets
+set(path "SimpleITKConfig.cmake.in")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+string(REPLACE "if(NOT ITK_TARGETS_IMPORTED)" "if(NOT TARGET ITKCommon)" contents ${contents})
+set(CONTENTS ${contents})
+string(REPLACE "if(NOT SimpleITK_TARGETS_IMPORTED)" "if(NOT TARGET SimpleITKCommon)" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
diff --git a/CMakeExternals/Python.cmake b/CMakeExternals/Python.cmake
new file mode 100644
index 0000000000..58e5718c7d
--- /dev/null
+++ b/CMakeExternals/Python.cmake
@@ -0,0 +1,175 @@
+#----------------------------------------------------------------------
+# Python
+#----------------------------------------------------------------------
+if( MITK_USE_Python AND NOT MITK_USE_SYSTEM_PYTHON )
+ # Sanity checks
+ if(DEFINED Python_DIR AND NOT EXISTS ${Python_DIR})
+ message(FATAL_ERROR "Python_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if(NOT DEFINED Python_DIR)
+ set(proj Python)
+ set(Python_DEPENDENCIES ZLIB Python-src)
+ set(Python_DEPENDS ${proj})
+
+ set(MITK_PYTHON_MAJOR_VERSION 2)
+ set(MITK_PYTHON_MINOR_VERSION 7)
+ set(MITK_PYTHON_PATCH_VERSION 3)
+
+ set(PYTHON_SOURCE_PACKAGE Python-${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}.${MITK_PYTHON_PATCH_VERSION})
+ set(PYTHON_SOURCE_DIR "${CMAKE_BINARY_DIR}/${PYTHON_SOURCE_PACKAGE}")
+ # patch the VS compiler config
+
+ if(WIN32)
+ set(PYTHON_PATCH_COMMAND PATCH_COMMAND ${CMAKE_COMMAND} -DPYTHON_SOURCE_DIR:PATH=${PYTHON_SOURCE_DIR} -P ${CMAKE_CURRENT_LIST_DIR}/Patch${proj}.cmake)
+ endif()
+
+ # download the source code
+ ExternalProject_Add(Python-src
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/${PYTHON_SOURCE_PACKAGE}.tgz
+ URL_MD5 "2cf641732ac23b18d139be077bd906cd"
+ PREFIX ${CMAKE_BINARY_DIR}/${PYTHON_SOURCE_PACKAGE}-cmake
+ SOURCE_DIR "${PYTHON_SOURCE_DIR}"
+ ${PYTHON_PATCH_COMMAND}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+ set(additional_cmake_cache_args )
+ list(APPEND additional_cmake_cache_args
+ -DBUILTIN_ARRAY:BOOL=ON
+ -DBUILTIN_AUDIOOP:BOOL=ON
+ -DBUILTIN_BINASCII:BOOL=ON
+ -DBUILTIN_BISECT:BOOL=ON
+ -DBUILTIN_BSDB:BOOL=ON
+ -DBUILTIN_BSSDB:BOOL=ON
+ -DBUILTIN_BZ2:BOOL=ON
+ -DBUILTIN_CMATH:BOOL=ON
+ -DBUILTIN_COLLECTIONS:BOOL=ON
+ -DBUILTIN_CODECS_CN:BOOL=ON
+ -DBUILTIN_CODECS_HK:BOOL=ON
+ -DBUILTIN_CODECS_ISO2022:BOOL=ON
+ -DBUILTIN_CODECS_JP:BOOL=ON
+ -DBUILTIN_CODECS_KR:BOOL=ON
+ -DBUILTIN_CODECS_TW:BOOL=ON
+ -DBUILTIN_CPICKLE:BOOL=ON
+ -DBUILTIN_CRYPT:BOOL=ON
+ -DBUILTIN_CSTRINGIO:BOOL=ON
+ -DBUILTIN_CSV:BOOL=ON
+ -DBUILTIN_CTYPES:BOOL=OFF
+ #-DBUILTIN_CTYPES_TEST:BOOL=OFF
+ #-DBUILTIN_CURSES:BOOL=ON
+ -DBUILTIN_DATETIME:BOOL=ON
+ -DBUILTIN_DBM:BOOL=ON
+ -DBUILTIN_ELEMENTTREE:BOOL=ON
+ -DBUILTIN_FCNTL:BOOL=ON
+ -DBUILTIN_FUNCTOOLS:BOOL=ON
+ -DBUILTIN_FUTURE_BUILTINS:BOOL=ON
+ -DBULTIN_GDBM:BOOL=ON
+ -DBUILTIN_GRP:BOOL=ON
+ -DBUILTIN_HASHLIB:BOOL=ON
+ -DBUILTIN_HEAPQ:BOOL=ON
+ -DBUILTIN_HOTSHOT:BOOL=ON
+ -DBUILTIN_IO:BOOL=ON
+ -DBUILTIN_ITERTOOLS:BOOL=ON
+ -DBUILTIN_JSON:BOOL=ON
+ -DBUILTIN_LOCALE:BOOL=ON
+ -DBUILTIN_LSPROF:BOOL=ON
+ -DBUILTIN_MATH:BOOL=ON
+ -DBUILTIN_MMAP:BOOL=ON
+ -DBUILTIN_MULTIBYTECODEC:BOOL=ON
+ -DBUILTIN_MD5:BOOL=ON
+ -DBUILTIN_MULTIPROCESSING:BOOL=ON
+ -DBUILTIN_NIS:BOOL=ON
+ -DBUILTIN_NIT:BOOL=ON
+ -DBUILTIN_OPERATOR:BOOL=ON
+ -DBUILTIN_PARSER:BOOL=ON
+ -DBUILTIN_POSIX:BOOL=ON
+ -DBUILTIN_PWD:BOOL=ON
+ -DBUILTIN_PYEXPAT:BOOL=ON
+ -DBUILTIN_READLINE:BOOL=ON
+ -DBUILTIN_RESOURCE:BOOL=ON
+ -DBULTIN_RANDOM:BOOL=ON
+ -DBUILTIN_SCPROXY:BOOL=OFF
+ -DBUILTIN_SELECT:BOOL=ON
+ -DBUILTIN_SHA:BOOL=ON
+ -DBUILTIN_SHA256:BOOL=ON
+ -DBUILTIN_SHA512:BOOL=ON
+ -DBUILTIN_SOCKET:BOOL=ON
+ -DBUILTIN_SPWD:BOOL=ON
+ -DBUILTIN_SQLITE3:BOOL=OFF
+ -DBUILTIN_SSL:BOOL=ON
+ -DBUILTIN_STROP:BOOL=ON
+ -DBUILTIN_STRUCT:BOOL=ON
+ -DBUILTIN_SUBPROCESS:BOOL=ON
+ -DBUILTIN_SYSLOG:BOOL=ON
+ -DBUILTIN_TERMIOS:BOOL=ON
+ #-DBUILTIN_TESTCAPI:BOOL=OFF
+ -DBUILTIN_TIME:BOOL=ON
+ -DBUILTIN_TKINTER:BOOL=ON
+ -DBUILTIN_UNICODEDATA:BOOL=ON
+ -DBUILTIN_WINREG:BOOL=ON
+ -DBUILTIN_ZLIB:BOOL=OFF
+ -DUSE_SYSTEM_ZLIB:BOOL=ON
+ )
+
+ # CMake build environment for python from:
+ # https://github.com/davidsansome/python-cmake-buildsystem
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/python-cmake-buildsystem-47845c55.tar.gz
+ URL_MD5 "6e49d1ed93a5a0fff7621430c163d2d1"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ PREFIX ${proj}-cmake
+ BINARY_DIR ${proj}-build
+ INSTALL_DIR ${proj}-install
+ CMAKE_ARGS
+ ${ep_common_args}
+ -DCMAKE_INSTALL_PREFIX:PATH=
+ CMAKE_CACHE_ARGS
+ -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
+ -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
+ #-DBUILD_TESTING:BOOL=OFF
+ -DBUILD_SHARED:BOOL=ON
+ -DBUILD_STATIC:BOOL=OFF
+ -DUSE_SYSTEM_LIBRARIES:BOOL=OFF
+ ${additional_cmake_cache_args}
+ -DZLIB_INCLUDE_DIR:PATH=${ZLIB_INCLUDE_DIR}
+ -DZLIB_LIBRARY:FILEPATH=${ZLIB_LIBRARY}
+ DEPENDS
+ ${Python_DEPENDENCIES}
+ )
+
+ set(Python_DIR "${CMAKE_BINARY_DIR}/${proj}-install")
+
+ if(UNIX)
+ set(PYTHON_EXECUTABLE "${Python_DIR}/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ set(PYTHON_INCLUDE_DIR "${Python_DIR}/include/python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}")
+ set(PYTHON_LIBRARY "${Python_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ set(MITK_PYTHON_SITE_DIR "${Python_DIR}/lib/python${MITK_PYTHON_MAJOR_VERSION}.${MITK_PYTHON_MINOR_VERSION}/site-packages")
+ else()
+ set(PYTHON_EXECUTABLE "${Python_DIR}/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ set(PYTHON_INCLUDE_DIR "${Python_DIR}/include")
+ set(PYTHON_LIBRARY "${Python_DIR}/libs/python${MITK_PYTHON_MAJOR_VERSION}${MITK_PYTHON_MINOR_VERSION}.lib")
+ set(MITK_PYTHON_SITE_DIR "${Python_DIR}/Lib/site-packages")
+ endif()
+
+ # pre compile all *.py files in the runtime after install step
+ ExternalProject_Add_Step(${proj} compile_step
+ COMMAND ${PYTHON_EXECUTABLE} -m compileall
+ DEPENDEES install
+ )
+
+ # use the python executable in the build dir for unix systems. The stripped
+ # ones will cause conflicts if system libraries are present during the build/configure process
+ # of opencv, since they will try to lookup the sys path first if no lib is directly
+ # linked with it s path into the executable
+ if(UNIX)
+ set(PYTHON_EXECUTABLE "${CMAKE_BINARY_DIR}/${proj}-build/bin/python${CMAKE_EXECUTABLE_SUFFIX}")
+ endif()
+
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeExternals/SimpleITK.cmake b/CMakeExternals/SimpleITK.cmake
new file mode 100644
index 0000000000..0e394acf42
--- /dev/null
+++ b/CMakeExternals/SimpleITK.cmake
@@ -0,0 +1,128 @@
+#-----------------------------------------------------------------------------
+# SimpleITK
+#-----------------------------------------------------------------------------
+
+if(MITK_USE_SimpleITK)
+
+ # Sanity checks
+ if(DEFINED SimpleITK_DIR AND NOT EXISTS ${SimpleITK_DIR})
+ message(FATAL_ERROR "SimpleITK_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ set(proj SimpleITK)
+ set(proj_DEPENDENCIES ITK GDCM Swig)
+
+ if(MITK_USE_OpenCV)
+ list(APPEND proj_DEPENDENCIES OpenCV)
+ endif()
+
+ set(SimpleITK_DEPENDS ${proj})
+
+ if(NOT DEFINED SimpleITK_DIR)
+
+ set(additional_cmake_args )
+
+ list(APPEND additional_cmake_args
+ -DWRAP_CSHARP:BOOL=OFF
+ -DWRAP_TCL:BOOL=OFF
+ -DWRAP_LUA:BOOL=OFF
+ -DWRAP_PYTHON:BOOL=OFF
+ -DWRAP_JAVA:BOOL=OFF
+ -DWRAP_RUBY:BOOL=OFF
+ -DWRAP_R:BOOL=OFF
+ )
+
+ if(MITK_USE_Python)
+ list(APPEND additional_cmake_args
+ -DWRAP_PYTHON:BOOL=ON
+ -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
+ -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
+ -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
+ -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
+ )
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
+ endif()
+
+ #TODO: Installer and testing works only with static libs on MAC
+ set(_build_shared ON)
+ if(APPLE)
+ set(_build_shared OFF)
+ endif()
+
+ set(SimpleITK_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchSimpleITK.cmake)
+
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/SimpleITK-0.8.0.tar.gz
+ URL_MD5 "d98f2e5442228e324ef62111febc7446"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${proj}-build
+ PREFIX ${proj}-cmake
+ INSTALL_DIR ${proj}-install
+ PATCH_COMMAND ${SimpleITK_PATCH_COMMAND}
+ CMAKE_ARGS
+ ${ep_common_args}
+ # -DCMAKE_BUILD_WITH_INSTALL_RPATH:BOOL=ON
+ CMAKE_CACHE_ARGS
+ ${additional_cmake_args}
+ -DBUILD_SHARED_LIBS:BOOL=${_build_shared}
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ -DCMAKE_INSTALL_NAME_DIR:STRING=/lib
+ -DSimpleITK_BUILD_DISTRIBUTE:BOOL=ON
+ -DSimpleITK_PYTHON_THREADS:BOOL=ON
+ -DUSE_SYSTEM_ITK:BOOL=ON
+ -DBUILD_TESTING:BOOL=OFF
+ -DBUILD_EXAMPLES:BOOL=OFF
+ -DGDCM_DIR:PATH=${GDCM_DIR}
+ -DITK_DIR:PATH=${ITK_DIR}
+ -DSWIG_DIR:PATH=${SWIG_DIR}
+ -DSWIG_EXECUTABLE:FILEPATH=${SWIG_EXECUTABLE}
+ DEPENDS ${proj_DEPENDENCIES}
+ )
+
+ set(SimpleITK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
+
+ if( MITK_USE_Python )
+ # PythonDir needs to be fixed for the python interpreter by
+ # changing dir delimiter for Windows
+ set(_install_dir ${Python_DIR})
+ if(WIN32)
+ STRING(REPLACE "/" "\\\\" _install_dir ${Python_DIR})
+ endif()
+ # Build python distribution with easy install. If a own runtime is used
+ # embedd the egg into the site-package folder of the runtime
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ ExternalProject_Add_Step(${proj} sitk_python_install_step
+ COMMAND ${PYTHON_EXECUTABLE} setup.py install --prefix=${_install_dir}
+ DEPENDEES build
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ # Build egg into custom user base folder and deploy it later into installer
+ # https://pythonhosted.org/setuptools/easy_install.html#use-the-user-option-and-customize-pythonuserbase
+ else()
+ set(_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
+ if(WIN32)
+ set(_userbase_install ${SimpleITK_DIR}/Wrapping/PythonPackage/Lib/site-packages)
+ endif()
+ ExternalProject_Add_Step(${proj} sitk_create_userbase_step
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${_userbase_install}
+ DEPENDEES build
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ ExternalProject_Add_Step(${proj} sitk_python_install_step
+ COMMAND PYTHONUSERBASE=${SimpleITK_DIR}/Wrapping/PythonPackage ${PYTHON_EXECUTABLE} setup.py install --user
+ DEPENDEES sitk_create_userbase_step
+ WORKING_DIRECTORY ${SimpleITK_DIR}/Wrapping/PythonPackage
+ )
+ endif()
+ endif()
+
+ else()
+
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+
+ endif()
+
+endif()
+
diff --git a/CMakeExternals/Swig.cmake b/CMakeExternals/Swig.cmake
new file mode 100644
index 0000000000..550680dae7
--- /dev/null
+++ b/CMakeExternals/Swig.cmake
@@ -0,0 +1,64 @@
+#------------------------------------------------------------
+# SWIG (Simple Wrapper Interface Generator)
+#-----------------------------------------------------------
+if(MITK_USE_SWIG)
+ if(DEFINED Swig_DIR AND NOT EXISTS ${Swig_DIR})
+ message(FATAL_ERROR "Swig_DIR variable is defined but corresponds to non-existing directory")
+ endif()
+
+ if(NOT SWIG_DIR)
+ set(SWIG_TARGET_VERSION 3.0.2)
+ set(proj Swig)
+ set(Swig_DEPENDENCIES )
+ set(Swig_DEPENDS )
+
+ # binary SWIG for windows
+ if(WIN32)
+ set(swig_source_dir ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION})
+
+ # swig.exe available as pre-built binary on Windows:
+ ExternalProject_Add(Swig
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/swigwin-${SWIG_TARGET_VERSION}.zip
+ URL_MD5 "3f18de4fc09ab9abb0d3be37c11fbc8f"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ )
+
+ set(SWIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}) # path specified as source in ep
+ set(SWIG_EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/swigwin-${SWIG_TARGET_VERSION}/swig.exe)
+
+ else()
+
+ list(APPEND Swig_DEPENDENCIES PCRE)
+
+ # swig uses bison find it by cmake and pass it down
+ find_package(BISON)
+ set(BISON_FLAGS "" CACHE STRING "Flags used by bison")
+ mark_as_advanced( BISON_FLAGS)
+
+ ExternalProject_add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/swig-${SWIG_TARGET_VERSION}.tar.gz
+ URL_MD5 "62f9b0d010cef36a13a010dc530d0d41"
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build
+ INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install
+ PREFIX ${proj}-cmake
+ CONFIGURE_COMMAND /./configure
+ CC=${CMAKE_C_COMPILER}${CMAKE_C_COMPILER_ARG1}
+ LDFLAGS=${CMAKE_LINKER_FLAGS} ${CMAKE_LINKER_FLAGS_RELEASE}
+ CXX=${CMAKE_CXX_COMPILER}${CMAKE_CXX_COMPILER_ARG1}
+ --prefix=
+ --with-pcre-prefix=${PCRE_DIR}
+ --without-octave
+ --with-python=${PYTHON_EXECUTABLE}
+ DEPENDS ${Swig_DEPENDENCIES}
+ )
+
+ set(SWIG_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install/share/swig/${SWIG_TARGET_VERSION})
+ set(SWIG_EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/${proj}-install/bin/swig)
+
+ endif()
+ endif(NOT SWIG_DIR)
+endif()
diff --git a/CMakeExternals/VTK.cmake b/CMakeExternals/VTK.cmake
index a3ef5f7bd6..495f9a4e28 100644
--- a/CMakeExternals/VTK.cmake
+++ b/CMakeExternals/VTK.cmake
@@ -1,94 +1,95 @@
#-----------------------------------------------------------------------------
# VTK
#-----------------------------------------------------------------------------
if(WIN32)
option(VTK_USE_SYSTEM_FREETYPE OFF)
else(WIN32)
option(VTK_USE_SYSTEM_FREETYPE ON)
endif(WIN32)
# Sanity checks
if(DEFINED VTK_DIR AND NOT EXISTS ${VTK_DIR})
message(FATAL_ERROR "VTK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj VTK)
set(proj_DEPENDENCIES )
set(VTK_DEPENDS ${proj})
if(NOT DEFINED VTK_DIR)
set(additional_cmake_args )
if(MINGW)
set(additional_cmake_args
-DCMAKE_USE_WIN32_THREADS:BOOL=ON
-DCMAKE_USE_PTHREADS:BOOL=OFF
-DVTK_USE_VIDEO4WINDOWS:BOOL=OFF # no header files provided by MinGW
)
endif()
if(MITK_USE_Python)
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ list(APPEND proj_DEPENDENCIES Python)
+ endif()
list(APPEND additional_cmake_args
-DVTK_WRAP_PYTHON:BOOL=ON
-DVTK_USE_TK:BOOL=OFF
-DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- #-DPYTHON_LIBRARIES=${PYTHON_LIBRARY}
- #-DPYTHON_DEBUG_LIBRARIES=${PYTHON_DEBUG_LIBRARIES}
)
else()
list(APPEND additional_cmake_args
-DVTK_WRAP_PYTHON:BOOL=OFF
-DVTK_WINDOWS_PYTHON_DEBUGGABLE:BOOL=OFF
)
endif()
if(MITK_USE_QT)
list(APPEND additional_cmake_args
-DVTK_QT_VERSION:STRING=${DESIRED_QT_VERSION}
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
-DModule_vtkGUISupportQt:BOOL=ON
-DModule_vtkGUISupportQtWebkit:BOOL=ON
-DModule_vtkGUISupportQtSQL:BOOL=ON
-DModule_vtkRenderingQt:BOOL=ON
-DVTK_Group_Qt:BOOL=ON
)
endif()
set(VTK_URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/VTK-6.1.0.tar.gz)
set(VTK_URL_MD5 25e4dfb3bad778722dcaec80cd5dab7d)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${VTK_URL}
URL_MD5 ${VTK_URL_MD5}
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
-DVTK_WRAP_TCL:BOOL=OFF
-DVTK_WRAP_PYTHON:BOOL=OFF
-DVTK_WRAP_JAVA:BOOL=OFF
-DBUILD_SHARED_LIBS:BOOL=ON
-DVTK_USE_SYSTEM_FREETYPE:BOOL=${VTK_USE_SYSTEM_FREETYPE}
-DVTK_LEGACY_REMOVE:BOOL=ON
-DModule_vtkTestingRendering:BOOL=ON
-DVTK_MAKE_INSTANTIATORS:BOOL=ON
${additional_cmake_args}
DEPENDS ${proj_DEPENDENCIES}
)
set(VTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
diff --git a/CMakeExternals/ZLIB.cmake b/CMakeExternals/ZLIB.cmake
new file mode 100644
index 0000000000..57310a059f
--- /dev/null
+++ b/CMakeExternals/ZLIB.cmake
@@ -0,0 +1,39 @@
+#------------------------------------------------------------------
+# ZLIB
+#------------------------------------------------------------------
+if(MITK_USE_ZLIB)
+ if(NOT DEFINED ZLIB_DIR)
+ set(proj ZLIB)
+ set(${proj}_DEPENDENCIES )
+ set(ZLIB_DEPENDS ${proj})
+
+ # Using the ZLIB from CTK:
+ # https://github.com/commontk/zlib
+ ExternalProject_Add(${proj}
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/zlib-66a75305.tar.gz
+ URL_MD5 "4c3f572b487ae7947fd88ec363533bc5"
+ SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
+ BINARY_DIR ${proj}-build
+ PREFIX ${proj}-cmake
+ INSTALL_DIR ${proj}-install
+ CMAKE_ARGS
+ ${ep_common_args}
+ CMAKE_CACHE_ARGS
+ -DBUILD_SHARED_LIBS:BOOL=OFF
+ -DZLIB_MANGLE_PREFIX:STRING=mitk_zlib_
+ -DCMAKE_INSTALL_PREFIX:PATH=
+ DEPENDS
+ ${ZLIB_DEPENDENCIES}
+ )
+ set(ZLIB_DIR ${CMAKE_BINARY_DIR}/${proj}-install)
+ set(ZLIB_INCLUDE_DIR ${ZLIB_DIR}/include)
+ if(WIN32)
+ set(ZLIB_LIBRARY ${ZLIB_DIR}/lib/zlib.lib)
+ else()
+ set(ZLIB_LIBRARY ${ZLIB_DIR}/lib/libzlib.a)
+ endif()
+ else()
+ mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
+ endif()
+endif()
+
diff --git a/CMakeExternals/msvc9compiler.py.patched b/CMakeExternals/msvc9compiler.py.patched
new file mode 100644
index 0000000000..daf78685a2
--- /dev/null
+++ b/CMakeExternals/msvc9compiler.py.patched
@@ -0,0 +1,924 @@
+"""distutils.msvc9compiler
+
+Contains MSVCCompiler, an implementation of the abstract CCompiler class
+for the Microsoft Visual Studio 2008.
+
+The module is compatible with VS 2005 and VS 2008. You can find legacy support
+for older versions of VS in distutils.msvccompiler.
+"""
+
+# Written by Perry Stoll
+# hacked by Robin Becker and Thomas Heller to do a better job of
+# finding DevStudio (through the registry)
+# ported to VS2005 and VS 2008 by Christian Heimes
+
+__revision__ = "$Id$"
+
+import os
+import subprocess
+import sys
+import re
+
+from distutils.errors import (DistutilsExecError, DistutilsPlatformError,
+ CompileError, LibError, LinkError)
+from distutils.ccompiler import CCompiler, gen_lib_options
+from distutils import log
+from distutils.util import get_platform
+
+import _winreg
+
+RegOpenKeyEx = _winreg.OpenKeyEx
+RegEnumKey = _winreg.EnumKey
+RegEnumValue = _winreg.EnumValue
+RegError = _winreg.error
+
+HKEYS = (_winreg.HKEY_USERS,
+ _winreg.HKEY_CURRENT_USER,
+ _winreg.HKEY_LOCAL_MACHINE,
+ _winreg.HKEY_CLASSES_ROOT)
+
+NATIVE_WIN64 = (sys.platform == 'win32' and sys.maxsize > 2**32)
+if NATIVE_WIN64:
+ # Visual C++ is a 32-bit application, so we need to look in
+ # the corresponding registry branch, if we're running a
+ # 64-bit Python on Win64
+ VS_BASE = r"Software\Wow6432Node\Microsoft\VisualStudio\%0.1f"
+ VSEXPRESS_BASE = r"Software\Wow6432Node\Microsoft\VCExpress\%0.1f"
+ WINSDK_BASE = r"Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows"
+ NET_BASE = r"Software\Wow6432Node\Microsoft\.NETFramework"
+ VC_SXS_KEY = r"Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7"
+ VS_SXS_KEY = r"Software\Wow6432Node\Microsoft\VisualStudio\SxS\VS7"
+else:
+ VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
+ VSEXPRESS_BASE = r"Software\Microsoft\VCExpress\%0.1f"
+ WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
+ NET_BASE = r"Software\Microsoft\.NETFramework"
+ VC_SXS_KEY = r"Software\Microsoft\VisualStudio\SxS\VC7"
+ VS_SXS_KEY = r"Software\Microsoft\VisualStudio\SxS\VS7"
+
+# A map keyed by get_platform() return values to values accepted by
+# 'vcvarsall.bat'. Note a cross-compile may combine these (eg, 'x86_amd64' is
+# the param to cross-compile on x86 targetting amd64.)
+PLAT_TO_VCVARS = {
+ 'win32' : 'x86',
+ 'win-amd64' : 'amd64',
+ 'win-ia64' : 'ia64',
+}
+
+# Add the first found value of InstallationFolder from this list of
+# keys to %PATH%
+KEY_BASE = r"Software\Microsoft\\"
+WINSDK_KEYS = [KEY_BASE + "Microsoft SDKs\\Windows\\" + rest for rest in (
+ r"v%s",
+ r"v%sA"
+)]
+
+# A map from VC version to Windows SDK version, to be used as the format
+# parameter for each element of WINSDK_KEYS.
+# See the following page for more details:
+# - http://en.wikipedia.org/wiki/Microsoft_Windows_SDK#Versions
+# - http://en.wikipedia.org/wiki/Microsoft_Visual_Studio#History
+WINSDK_VERSION_MAP = {
+ '9.0': ['6.0', '7.0'], # VS2008
+ '10.0': ['7.0', '7.1'], # VS2010
+ '11.0': ['7.1', '8.0', '8.1'], # VS2012
+}
+
+class Reg:
+ """Helper class to read values from the registry
+ """
+
+ def get_value(cls, path, key):
+ for base in HKEYS:
+ d = cls.read_values(base, path)
+ if d and key in d:
+ return d[key]
+ raise KeyError(key)
+ get_value = classmethod(get_value)
+
+ def read_keys(cls, base, key):
+ """Return list of registry keys."""
+ try:
+ handle = RegOpenKeyEx(base, key)
+ except RegError:
+ return None
+ L = []
+ i = 0
+ while True:
+ try:
+ k = RegEnumKey(handle, i)
+ except RegError:
+ break
+ L.append(k)
+ i += 1
+ return L
+ read_keys = classmethod(read_keys)
+
+ def read_values(cls, base, key):
+ """Return dict of registry keys and values.
+
+ All names are converted to lowercase.
+ """
+ try:
+ handle = RegOpenKeyEx(base, key)
+ except RegError:
+ return None
+ d = {}
+ i = 0
+ while True:
+ try:
+ name, value, type = RegEnumValue(handle, i)
+ except RegError:
+ break
+ name = name.lower()
+ d[cls.convert_mbcs(name)] = cls.convert_mbcs(value)
+ i += 1
+ return d
+ read_values = classmethod(read_values)
+
+ def convert_mbcs(s):
+ dec = getattr(s, "decode", None)
+ if dec is not None:
+ try:
+ s = dec("mbcs")
+ except UnicodeError:
+ pass
+ return s
+ convert_mbcs = staticmethod(convert_mbcs)
+
+class MacroExpander:
+
+ def __init__(self, version):
+ self.macros = {}
+ self.vsbase = VS_BASE % version
+ self.load_macros(version)
+
+ def set_macro(self, macro, path, key):
+ self.macros["$(%s)" % macro] = Reg.get_value(path, key)
+
+ def load_macros(self, version):
+ self.set_macro("VCInstallDir", self.vsbase + r"\Setup\VC", "productdir")
+ self.set_macro("VSInstallDir", self.vsbase + r"\Setup\VS", "productdir")
+ self.set_macro("FrameworkDir", NET_BASE, "installroot")
+ try:
+ if version >= 8.0:
+ self.set_macro("FrameworkSDKDir", NET_BASE,
+ "sdkinstallrootv2.0")
+ else:
+ raise KeyError("sdkinstallrootv2.0")
+ except KeyError:
+ raise DistutilsPlatformError(
+ """Python was built with Visual Studio 2008;
+extensions must be built with a compiler than can generate compatible binaries.
+Visual Studio 2008 was not found on this system. If you have Cygwin installed,
+you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
+
+ if version >= 9.0:
+ self.set_macro("FrameworkVersion", self.vsbase, "clr version")
+ self.set_macro("WindowsSdkDir", WINSDK_BASE, "currentinstallfolder")
+ else:
+ p = r"Software\Microsoft\NET Framework Setup\Product"
+ for base in HKEYS:
+ try:
+ h = RegOpenKeyEx(base, p)
+ except RegError:
+ continue
+ key = RegEnumKey(h, 0)
+ d = Reg.get_value(base, r"%s\%s" % (p, key))
+ self.macros["$(FrameworkVersion)"] = d["version"]
+
+ def sub(self, s):
+ for k, v in self.macros.items():
+ s = s.replace(k, v)
+ return s
+
+def get_build_version():
+ """Return the version of MSVC that was used to build Python.
+
+ For Python 2.3 and up, the version number is included in
+ sys.version. For earlier versions, assume the compiler is MSVC 6.
+ """
+ prefix = "MSC v."
+ i = sys.version.find(prefix)
+ if i == -1:
+ return 6
+ i = i + len(prefix)
+ s, rest = sys.version[i:].split(" ", 1)
+ majorVersion = int(s[:-2]) - 6
+ minorVersion = int(s[2:3]) / 10.0
+ # I don't think paths are affected by minor version in version 6
+ if majorVersion == 6:
+ minorVersion = 0
+ if majorVersion >= 6:
+ return majorVersion + minorVersion
+ # else we don't know what version of the compiler this is
+ return None
+
+def normalize_and_reduce_paths(paths):
+ """Return a list of normalized paths with duplicates removed.
+
+ The current order of paths is maintained.
+ """
+ # Paths are normalized so things like: /a and /a/ aren't both preserved.
+ reduced_paths = []
+ for p in paths:
+ np = os.path.normpath(p)
+ # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
+ if np not in reduced_paths:
+ reduced_paths.append(np)
+ return reduced_paths
+
+def removeDuplicates(variable):
+ """Remove duplicate values of an environment variable.
+ """
+ oldList = variable.split(os.pathsep)
+ newList = []
+ for i in oldList:
+ if i not in newList:
+ newList.append(i)
+ newVariable = os.pathsep.join(newList)
+ return newVariable
+
+# deprecated
+def find_vcvarsall(version):
+ """Find the vcvarsall.bat file
+
+ At first it tries to find the productdir of VS 2008 in the registry. If
+ that fails it falls back to the VS90COMNTOOLS env var.
+ """
+ vsbase = VS_BASE % version
+ try:
+ productdir = Reg.get_value(r"%s\Setup\VC" % vsbase,
+ "productdir")
+ except KeyError:
+ productdir = None
+
+ # trying Express edition
+ if productdir is None:
+ vsbase = VSEXPRESS_BASE % version
+ try:
+ productdir = Reg.get_value(r"%s\Setup\VC" % vsbase,
+ "productdir")
+ except KeyError:
+ productdir = None
+ log.debug("Unable to find productdir in registry")
+
+ if not productdir or not os.path.isdir(productdir):
+ toolskey = "VS%0.f0COMNTOOLS" % version
+ toolsdir = os.environ.get(toolskey, None)
+
+ if toolsdir and os.path.isdir(toolsdir):
+ productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC")
+ productdir = os.path.abspath(productdir)
+ if not os.path.isdir(productdir):
+ log.debug("%s is not a valid directory" % productdir)
+ return None
+ else:
+ log.debug("Env var %s is not set or invalid" % toolskey)
+ if not productdir:
+ log.debug("No productdir found")
+ return None
+ vcvarsall = os.path.join(productdir, "vcvarsall.bat")
+ if os.path.isfile(vcvarsall):
+ return vcvarsall
+ log.debug("Unable to find vcvarsall.bat")
+ return None
+
+def query_vcvarsall(version, arch="x86"):
+ """Launch vcvarsall.bat and read the settings from its environment
+ """
+
+ paths = []
+ includes = []
+ libs = []
+
+ def _append_if_exists(list_, path):
+ if os.path.isdir(path):
+ list_.append(path)
+
+ def _add_bin_paths(base, paths):
+ if arch.endswith("ia64"):
+ _append_if_exists(paths, base + r"\bin\ia64")
+ elif arch.endswith("64"):
+ _append_if_exists(paths, base + r"\bin\x64")
+ _append_if_exists(paths, base + r"\bin\amd64")
+ elif arch.endswith("x86"):
+ _append_if_exists(paths, base + r"\bin")
+
+ def _get_include_lib_paths(base):
+ existing_includes = []
+ existing_libs = []
+ _append_if_exists(existing_includes, base + r"\include")
+ if arch.endswith("ia64"):
+ _append_if_exists(existing_libs, base + r"\lib\ia64")
+ elif arch.endswith("64"):
+ _append_if_exists(existing_libs, base + r"\lib\x64")
+ _append_if_exists(existing_libs, base + r"\lib\amd64")
+ elif arch.endswith("x86"):
+ _append_if_exists(existing_libs, base + r"\lib")
+
+ return (existing_includes, existing_libs)
+
+ result = []
+
+ versionstr = '%.1f' % version
+
+ vcpaths = Reg.read_values(_winreg.HKEY_LOCAL_MACHINE, VC_SXS_KEY)
+ vcinstalldir = vcpaths[versionstr]
+ vsinstalldir = Reg.read_values(_winreg.HKEY_LOCAL_MACHINE, VS_SXS_KEY).get(versionstr, vcinstalldir + "..")
+
+ # set PATH to include:
+ # %VCINSTALLDIR%\bin[\x64|\amd64|\ia64]
+ # %VCINSTALLDIR%\VCPackages
+
+ if vcinstalldir:
+ _add_bin_paths(vcinstalldir, paths)
+ _append_if_exists(paths, "%s\\VCPackages" % (vcinstalldir))
+
+ # set PATH to include:
+ # %VSINSTALLDIR%\Common7\IDE
+ # %VSINSTALLDIR%\Common7\Tools
+ # %VSINSTALLDIR%\Common7\Tools\bin
+
+ if vsinstalldir:
+ _append_if_exists(paths, "%s\\Common7\\IDE" % (vsinstalldir))
+ _append_if_exists(paths, "%s\\Common7\\Tools" % (vsinstalldir))
+ _append_if_exists(paths, "%s\\Common7\\Tools\\bin" % (vsinstalldir))
+
+ # set PATH to include:
+ # %FrameworkDir%\%Framework35Version%
+ # %FrameworkDir%\%FrameworkVersion%
+
+ frameworkdir = vcpaths.get("frameworkdir64" if arch == "amd64" else "frameworkdir32")
+ if frameworkdir:
+ _append_if_exists(paths, frameworkdir + r"\v3.5")
+ frameworkver = vcpaths.get("frameworkver64" if arch == "amd64" else "frameworkdir32")
+ if frameworkver:
+ _append_if_exists(paths, r"%s\%s" % (frameworkdir, frameworkver))
+
+ def _get_sdk_installationfolder(sdkver):
+ for sdkkey in WINSDK_KEYS:
+ try:
+ sdk_install = Reg.get_value(sdkkey % sdkver, "installationfolder")
+ except KeyError:
+ pass
+ else:
+ return sdk_install
+ return None
+
+ sdk_available = False
+
+ for sdkver in WINSDK_VERSION_MAP[versionstr]:
+
+ # set PATH to include:
+ # %WindowsSdkDir%bin[\x64|\amd64|\ia64]
+ # set INCLUDE to include:
+ # %WindowsSdkDir%include
+ # and LIB to include
+ # %WindowsSdkDir%lib[\x64|\amd64|\ia64]
+
+ sdk_install = _get_sdk_installationfolder(sdkver)
+ if sdk_install is not None:
+ (sdk_includes, sdk_libs) = _get_include_lib_paths(sdk_install)
+ sdk_available = len(sdk_includes) > 0 and len(sdk_libs) > 0
+ if sdk_available:
+ _add_bin_paths(sdk_install, paths)
+ includes += sdk_includes
+ libs += sdk_libs
+ print("Windows SDK %s complete" % sdkver)
+ break
+ else:
+ print("Windows SDK %s incomplete" % sdkver)
+ else:
+ print("Windows SDK %s not found" % sdkver)
+
+ # set INCLUDE to include:
+ # %VCINSTALLDIR%\include
+ # and LIB to include
+ # %VCINSTALLDIR%\lib[\x64|\amd64|\ia64]
+
+ if vcinstalldir:
+ (vc_includes, vc_libs) = _get_include_lib_paths(vcinstalldir)
+ includes += vc_includes
+ libs += vc_libs
+
+ result = {
+ "path": ";".join(paths),
+ "include": ";".join(includes),
+ "lib": ";".join(libs),
+ }
+
+ print("Start -----------------------------------------")
+ import pprint as pp
+ for k in result.keys():
+ print(">>>>>> key:%s" % k)
+ pp.pprint(result[k].split(';'))
+ print("End -----------------------------------------")
+
+ return result
+
+# More globals
+VERSION = get_build_version()
+if VERSION < 8.0:
+ raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
+# MACROS = MacroExpander(VERSION)
+
+class MSVCCompiler(CCompiler) :
+ """Concrete class that implements an interface to Microsoft Visual C++,
+ as defined by the CCompiler abstract class."""
+
+ compiler_type = 'msvc'
+
+ # Just set this so CCompiler's constructor doesn't barf. We currently
+ # don't use the 'set_executables()' bureaucracy provided by CCompiler,
+ # as it really isn't necessary for this sort of single-compiler class.
+ # Would be nice to have a consistent interface with UnixCCompiler,
+ # though, so it's worth thinking about.
+ executables = {}
+
+ # Private class data (need to distinguish C from C++ source for compiler)
+ _c_extensions = ['.c']
+ _cpp_extensions = ['.cc', '.cpp', '.cxx']
+ _rc_extensions = ['.rc']
+ _mc_extensions = ['.mc']
+
+ # Needed for the filename generation methods provided by the
+ # base class, CCompiler.
+ src_extensions = (_c_extensions + _cpp_extensions +
+ _rc_extensions + _mc_extensions)
+ res_extension = '.res'
+ obj_extension = '.obj'
+ static_lib_extension = '.lib'
+ shared_lib_extension = '.dll'
+ static_lib_format = shared_lib_format = '%s%s'
+ exe_extension = '.exe'
+
+ def __init__(self, verbose=0, dry_run=0, force=0):
+ CCompiler.__init__ (self, verbose, dry_run, force)
+ self.__version = VERSION
+ self.__root = r"Software\Microsoft\VisualStudio"
+ # self.__macros = MACROS
+ self.__paths = []
+ # target platform (.plat_name is consistent with 'bdist')
+ self.plat_name = None
+ self.__arch = None # deprecated name
+ self.initialized = False
+
+ def initialize(self, plat_name=None):
+ # multi-init means we would need to check platform same each time...
+ assert not self.initialized, "don't init multiple times"
+ if plat_name is None:
+ plat_name = get_platform()
+ # sanity check for platforms to prevent obscure errors later.
+ ok_plats = 'win32', 'win-amd64', 'win-ia64'
+ if plat_name not in ok_plats:
+ raise DistutilsPlatformError("--plat-name must be one of %s" %
+ (ok_plats,))
+
+ if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
+ # Assume that the SDK set up everything alright; don't try to be
+ # smarter
+ self.cc = "cl.exe"
+ self.linker = "link.exe"
+ self.lib = "lib.exe"
+ self.rc = "rc.exe"
+ self.mc = "mc.exe"
+ else:
+ # On x86, 'vcvars32.bat amd64' creates an env that doesn't work;
+ # to cross compile, you use 'x86_amd64'.
+ # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross
+ # compile use 'x86' (ie, it runs the x86 compiler directly)
+ # No idea how itanium handles this, if at all.
+ if plat_name == get_platform() or plat_name == 'win32':
+ # native build or cross-compile to win32
+ plat_spec = PLAT_TO_VCVARS[plat_name]
+ else:
+ # cross compile from win32 -> some 64bit
+ plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \
+ PLAT_TO_VCVARS[plat_name]
+
+ vc_env = query_vcvarsall(VERSION, plat_spec)
+
+ # take care to only use strings in the environment.
+ self.__paths = vc_env['path'].encode('mbcs').split(os.pathsep)
+ os.environ['lib'] = vc_env['lib'].encode('mbcs')
+ os.environ['include'] = vc_env['include'].encode('mbcs')
+
+ if len(self.__paths) == 0:
+ raise DistutilsPlatformError("Python was built with %s, "
+ "and extensions need to be built with the same "
+ "version of the compiler, but it isn't installed."
+ % self.__product)
+
+ self.cc = self.find_exe("cl.exe")
+ self.linker = self.find_exe("link.exe")
+ self.lib = self.find_exe("lib.exe")
+ self.rc = self.find_exe("rc.exe") # resource compiler
+ self.mc = self.find_exe("mc.exe") # message compiler
+ #self.set_path_env_var('lib')
+ #self.set_path_env_var('include')
+
+ # extend the MSVC path with the current path
+ try:
+ for p in os.environ['path'].split(';'):
+ self.__paths.append(p)
+ except KeyError:
+ pass
+ self.__paths = normalize_and_reduce_paths(self.__paths)
+ os.environ['path'] = ";".join(self.__paths)
+
+ self.preprocess_options = None
+ if self.__arch == "x86":
+ self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3',
+ '/DNDEBUG']
+ self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3',
+ '/Z7', '/D_DEBUG']
+ else:
+ # Win64
+ self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
+ '/DNDEBUG']
+ self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
+ '/Z7', '/D_DEBUG']
+
+ self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
+ if self.__version >= 10:
+ self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO', '/Manifest']
+ if self.__version >= 7:
+ self.ldflags_shared_debug = [
+ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None'
+ ]
+ if self.__version >= 10:
+ self.ldflags_shared_debug = [
+ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None', '/Manifest'
+ ]
+ self.ldflags_static = [ '/nologo']
+
+ self.initialized = True
+
+ # -- Worker methods ------------------------------------------------
+
+ def object_filenames(self,
+ source_filenames,
+ strip_dir=0,
+ output_dir=''):
+ # Copied from ccompiler.py, extended to return .res as 'object'-file
+ # for .rc input file
+ if output_dir is None: output_dir = ''
+ obj_names = []
+ for src_name in source_filenames:
+ (base, ext) = os.path.splitext (src_name)
+ base = os.path.splitdrive(base)[1] # Chop off the drive
+ base = base[os.path.isabs(base):] # If abs, chop off leading /
+ if ext not in self.src_extensions:
+ # Better to raise an exception instead of silently continuing
+ # and later complain about sources and targets having
+ # different lengths
+ raise CompileError ("Don't know how to compile %s" % src_name)
+ if strip_dir:
+ base = os.path.basename (base)
+ if ext in self._rc_extensions:
+ obj_names.append (os.path.join (output_dir,
+ base + self.res_extension))
+ elif ext in self._mc_extensions:
+ obj_names.append (os.path.join (output_dir,
+ base + self.res_extension))
+ else:
+ obj_names.append (os.path.join (output_dir,
+ base + self.obj_extension))
+ return obj_names
+
+
+ def compile(self, sources,
+ output_dir=None, macros=None, include_dirs=None, debug=0,
+ extra_preargs=None, extra_postargs=None, depends=None):
+
+ if not self.initialized:
+ self.initialize()
+ compile_info = self._setup_compile(output_dir, macros, include_dirs,
+ sources, depends, extra_postargs)
+ macros, objects, extra_postargs, pp_opts, build = compile_info
+
+ compile_opts = extra_preargs or []
+ compile_opts.append ('/c')
+ if debug:
+ compile_opts.extend(self.compile_options_debug)
+ else:
+ compile_opts.extend(self.compile_options)
+
+ for obj in objects:
+ try:
+ src, ext = build[obj]
+ except KeyError:
+ continue
+ if debug:
+ # pass the full pathname to MSVC in debug mode,
+ # this allows the debugger to find the source file
+ # without asking the user to browse for it
+ src = os.path.abspath(src)
+
+ if ext in self._c_extensions:
+ input_opt = "/Tc" + src
+ elif ext in self._cpp_extensions:
+ input_opt = "/Tp" + src
+ elif ext in self._rc_extensions:
+ # compile .RC to .RES file
+ input_opt = src
+ output_opt = "/fo" + obj
+ try:
+ self.spawn([self.rc] + pp_opts +
+ [output_opt] + [input_opt])
+ except DistutilsExecError, msg:
+ raise CompileError(msg)
+ continue
+ elif ext in self._mc_extensions:
+ # Compile .MC to .RC file to .RES file.
+ # * '-h dir' specifies the directory for the
+ # generated include file
+ # * '-r dir' specifies the target directory of the
+ # generated RC file and the binary message resource
+ # it includes
+ #
+ # For now (since there are no options to change this),
+ # we use the source-directory for the include file and
+ # the build directory for the RC file and message
+ # resources. This works at least for win32all.
+ h_dir = os.path.dirname(src)
+ rc_dir = os.path.dirname(obj)
+ try:
+ # first compile .MC to .RC and .H file
+ self.spawn([self.mc] +
+ ['-h', h_dir, '-r', rc_dir] + [src])
+ base, _ = os.path.splitext (os.path.basename (src))
+ rc_file = os.path.join (rc_dir, base + '.rc')
+ # then compile .RC to .RES file
+ self.spawn([self.rc] +
+ ["/fo" + obj] + [rc_file])
+
+ except DistutilsExecError, msg:
+ raise CompileError(msg)
+ continue
+ else:
+ # how to handle this file?
+ raise CompileError("Don't know how to compile %s to %s"
+ % (src, obj))
+
+ output_opt = "/Fo" + obj
+ try:
+ self.spawn([self.cc] + compile_opts + pp_opts +
+ [input_opt, output_opt] +
+ extra_postargs)
+ except DistutilsExecError, msg:
+ raise CompileError(msg)
+
+ return objects
+
+
+ def create_static_lib(self,
+ objects,
+ output_libname,
+ output_dir=None,
+ debug=0,
+ target_lang=None):
+
+ if not self.initialized:
+ self.initialize()
+ (objects, output_dir) = self._fix_object_args(objects, output_dir)
+ output_filename = self.library_filename(output_libname,
+ output_dir=output_dir)
+
+ if self._need_link(objects, output_filename):
+ lib_args = objects + ['/OUT:' + output_filename]
+ if debug:
+ pass # XXX what goes here?
+ try:
+ self.spawn([self.lib] + lib_args)
+ except DistutilsExecError, msg:
+ raise LibError(msg)
+ else:
+ log.debug("skipping %s (up-to-date)", output_filename)
+
+
+ def link(self,
+ target_desc,
+ objects,
+ output_filename,
+ output_dir=None,
+ libraries=None,
+ library_dirs=None,
+ runtime_library_dirs=None,
+ export_symbols=None,
+ debug=0,
+ extra_preargs=None,
+ extra_postargs=None,
+ build_temp=None,
+ target_lang=None):
+
+ if not self.initialized:
+ self.initialize()
+ (objects, output_dir) = self._fix_object_args(objects, output_dir)
+ fixed_args = self._fix_lib_args(libraries, library_dirs,
+ runtime_library_dirs)
+ (libraries, library_dirs, runtime_library_dirs) = fixed_args
+
+ if runtime_library_dirs:
+ self.warn ("I don't know what to do with 'runtime_library_dirs': "
+ + str (runtime_library_dirs))
+
+ lib_opts = gen_lib_options(self,
+ library_dirs, runtime_library_dirs,
+ libraries)
+ if output_dir is not None:
+ output_filename = os.path.join(output_dir, output_filename)
+
+ if self._need_link(objects, output_filename):
+ if target_desc == CCompiler.EXECUTABLE:
+ if debug:
+ ldflags = self.ldflags_shared_debug[1:]
+ else:
+ ldflags = self.ldflags_shared[1:]
+ else:
+ if debug:
+ ldflags = self.ldflags_shared_debug
+ else:
+ ldflags = self.ldflags_shared
+
+ export_opts = []
+ for sym in (export_symbols or []):
+ export_opts.append("/EXPORT:" + sym)
+
+ ld_args = (ldflags + lib_opts + export_opts +
+ objects + ['/OUT:' + output_filename])
+
+ # The MSVC linker generates .lib and .exp files, which cannot be
+ # suppressed by any linker switches. The .lib files may even be
+ # needed! Make sure they are generated in the temporary build
+ # directory. Since they have different names for debug and release
+ # builds, they can go into the same directory.
+ build_temp = os.path.dirname(objects[0])
+ if export_symbols is not None:
+ (dll_name, dll_ext) = os.path.splitext(
+ os.path.basename(output_filename))
+ implib_file = os.path.join(
+ build_temp,
+ self.library_filename(dll_name))
+ ld_args.append ('/IMPLIB:' + implib_file)
+
+ self.manifest_setup_ldargs(output_filename, build_temp, ld_args)
+
+ if extra_preargs:
+ ld_args[:0] = extra_preargs
+ if extra_postargs:
+ ld_args.extend(extra_postargs)
+
+ self.mkpath(os.path.dirname(output_filename))
+ try:
+ self.spawn([self.linker] + ld_args)
+ except DistutilsExecError, msg:
+ raise LinkError(msg)
+
+ # embed the manifest
+ # XXX - this is somewhat fragile - if mt.exe fails, distutils
+ # will still consider the DLL up-to-date, but it will not have a
+ # manifest. Maybe we should link to a temp file? OTOH, that
+ # implies a build environment error that shouldn't go undetected.
+ mfinfo = self.manifest_get_embed_info(target_desc, ld_args)
+ if mfinfo is not None:
+ mffilename, mfid = mfinfo
+ out_arg = '-outputresource:%s;%s' % (output_filename, mfid)
+ try:
+ self.spawn(['mt.exe', '-nologo', '-manifest',
+ mffilename, out_arg])
+ except DistutilsExecError, msg:
+ raise LinkError(msg)
+ else:
+ log.debug("skipping %s (up-to-date)", output_filename)
+
+ def manifest_setup_ldargs(self, output_filename, build_temp, ld_args):
+ # If we need a manifest at all, an embedded manifest is recommended.
+ # See MSDN article titled
+ # "How to: Embed a Manifest Inside a C/C++ Application"
+ # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx)
+ # Ask the linker to generate the manifest in the temp dir, so
+ # we can check it, and possibly embed it, later.
+ temp_manifest = os.path.join(
+ build_temp,
+ os.path.basename(output_filename) + ".manifest")
+ ld_args.append('/MANIFESTFILE:' + temp_manifest)
+
+ def manifest_get_embed_info(self, target_desc, ld_args):
+ # If a manifest should be embedded, return a tuple of
+ # (manifest_filename, resource_id). Returns None if no manifest
+ # should be embedded. See http://bugs.python.org/issue7833 for why
+ # we want to avoid any manifest for extension modules if we can)
+ for arg in ld_args:
+ if arg.startswith("/MANIFESTFILE:"):
+ temp_manifest = arg.split(":", 1)[1]
+ break
+ else:
+ # no /MANIFESTFILE so nothing to do.
+ return None
+ if target_desc == CCompiler.EXECUTABLE:
+ # by default, executables always get the manifest with the
+ # CRT referenced.
+ mfid = 1
+ else:
+ # Extension modules try and avoid any manifest if possible.
+ mfid = 2
+ temp_manifest = self._remove_visual_c_ref(temp_manifest)
+ if temp_manifest is None:
+ return None
+ return temp_manifest, mfid
+
+ def _remove_visual_c_ref(self, manifest_file):
+ try:
+ # Remove references to the Visual C runtime, so they will
+ # fall through to the Visual C dependency of Python.exe.
+ # This way, when installed for a restricted user (e.g.
+ # runtimes are not in WinSxS folder, but in Python's own
+ # folder), the runtimes do not need to be in every folder
+ # with .pyd's.
+ # Returns either the filename of the modified manifest or
+ # None if no manifest should be embedded.
+ manifest_f = open(manifest_file)
+ try:
+ manifest_buf = manifest_f.read()
+ finally:
+ manifest_f.close()
+ pattern = re.compile(
+ r"""|)""",
+ re.DOTALL)
+ manifest_buf = re.sub(pattern, "", manifest_buf)
+ pattern = "\s*"
+ manifest_buf = re.sub(pattern, "", manifest_buf)
+ # Now see if any other assemblies are referenced - if not, we
+ # don't want a manifest embedded.
+ pattern = re.compile(
+ r"""|)""", re.DOTALL)
+ if re.search(pattern, manifest_buf) is None:
+ return None
+
+ manifest_f = open(manifest_file, 'w')
+ try:
+ manifest_f.write(manifest_buf)
+ return manifest_file
+ finally:
+ manifest_f.close()
+ except IOError:
+ pass
+
+ # -- Miscellaneous methods -----------------------------------------
+ # These are all used by the 'gen_lib_options() function, in
+ # ccompiler.py.
+
+ def library_dir_option(self, dir):
+ return "/LIBPATH:" + dir
+
+ def runtime_library_dir_option(self, dir):
+ raise DistutilsPlatformError(
+ "don't know how to set runtime library search path for MSVC++")
+
+ def library_option(self, lib):
+ return self.library_filename(lib)
+
+
+ def find_library_file(self, dirs, lib, debug=0):
+ # Prefer a debugging library if found (and requested), but deal
+ # with it if we don't have one.
+ if debug:
+ try_names = [lib + "_d", lib]
+ else:
+ try_names = [lib]
+ for dir in dirs:
+ for name in try_names:
+ libfile = os.path.join(dir, self.library_filename (name))
+ if os.path.exists(libfile):
+ return libfile
+ else:
+ # Oops, didn't find it in *any* of 'dirs'
+ return None
+
+ # Helper methods for using the MSVC registry settings
+
+ def find_exe(self, exe):
+ """Return path to an MSVC executable program.
+
+ Tries to find the program in several places: first, one of the
+ MSVC program search paths from the registry; next, the directories
+ in the PATH environment variable. If any of those work, return an
+ absolute path that is known to exist. If none of them work, just
+ return the original program name, 'exe'.
+ """
+ for p in self.__paths:
+ fn = os.path.join(os.path.abspath(p), exe)
+ if os.path.isfile(fn):
+ return fn
+
+ # didn't find it; try existing path
+ for p in os.environ['Path'].split(';'):
+ fn = os.path.join(os.path.abspath(p),exe)
+ if os.path.isfile(fn):
+ return fn
+
+ return exe
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fbda3fd3e3..1f9cf77483 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,1066 +1,1076 @@
set(DESIRED_QT_VERSION 4 CACHE STRING "Pick a version of Qt to use: 4 or 5")
if(DESIRED_QT_VERSION MATCHES "4")
cmake_minimum_required(VERSION 2.8.9)
else()
cmake_minimum_required(VERSION 2.8.12)
endif()
#-----------------------------------------------------------------------------
# Include ctest launchers for dashboard in case of makefile generator
#-----------------------------------------------------------------------------
if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
include(CTestUseLaunchers)
endif()
#-----------------------------------------------------------------------------
# Set a default build type if none was specified
#-----------------------------------------------------------------------------
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
#-----------------------------------------------------------------------------
# Superbuild Option - Enabled by default
#-----------------------------------------------------------------------------
option(MITK_USE_SUPERBUILD "Build MITK and the projects it depends on via SuperBuild.cmake." ON)
if(MITK_USE_SUPERBUILD)
project(MITK-superbuild)
set(MITK_SOURCE_DIR ${PROJECT_SOURCE_DIR})
set(MITK_BINARY_DIR ${PROJECT_BINARY_DIR})
else()
project(MITK)
endif()
#-----------------------------------------------------------------------------
# Warn if source or build path is too long
#-----------------------------------------------------------------------------
if(WIN32)
set(_src_dir_length_max 50)
set(_bin_dir_length_max 50)
if(MITK_USE_SUPERBUILD)
set(_src_dir_length_max 43) # _src_dir_length_max - strlen(ITK-src)
set(_bin_dir_length_max 40) # _bin_dir_length_max - strlen(MITK-build)
endif()
string(LENGTH "${MITK_SOURCE_DIR}" _src_n)
string(LENGTH "${MITK_BINARY_DIR}" _bin_n)
# The warnings should be converted to errors
if(_src_n GREATER _src_dir_length_max)
message(WARNING "MITK source code directory path length is too long (${_src_n} > ${_src_dir_length_max})."
"Please move the MITK source code directory to a directory with a shorter path." )
endif()
if(_bin_n GREATER _bin_dir_length_max)
message(WARNING "MITK build directory path length is too long (${_bin_n} > ${_bin_dir_length_max})."
"Please move the MITK build directory to a directory with a shorter path." )
endif()
endif()
#-----------------------------------------------------------------------------
# See http://cmake.org/cmake/help/cmake-2-8-docs.html#section_Policies for details
#-----------------------------------------------------------------------------
set(project_policies
CMP0001 # NEW: CMAKE_BACKWARDS_COMPATIBILITY should no longer be used.
CMP0002 # NEW: Logical target names must be globally unique.
CMP0003 # NEW: Libraries linked via full path no longer produce linker search paths.
CMP0004 # NEW: Libraries linked may NOT have leading or trailing whitespace.
CMP0005 # NEW: Preprocessor definition values are now escaped automatically.
CMP0006 # NEW: Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.
CMP0007 # NEW: List command no longer ignores empty elements.
CMP0008 # NEW: Libraries linked by full-path must have a valid library file name.
CMP0009 # NEW: FILE GLOB_RECURSE calls should not follow symlinks by default.
CMP0010 # NEW: Bad variable reference syntax is an error.
CMP0011 # NEW: Included scripts do automatic cmake_policy PUSH and POP.
CMP0012 # NEW: if() recognizes numbers and boolean constants.
CMP0013 # NEW: Duplicate binary directories are not allowed.
CMP0014 # NEW: Input directories must have CMakeLists.txt
CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows
)
foreach(policy ${project_policies})
if(POLICY ${policy})
cmake_policy(SET ${policy} NEW)
endif()
endforeach()
#-----------------------------------------------------------------------------
# Update CMake module path
#------------------------------------------------------------------------------
set(MITK_CMAKE_DIR ${MITK_SOURCE_DIR}/CMake)
set(CMAKE_MODULE_PATH
${MITK_CMAKE_DIR}
${CMAKE_MODULE_PATH}
)
#-----------------------------------------------------------------------------
# CMake function(s) and macro(s)
#-----------------------------------------------------------------------------
include(mitkMacroEmptyExternalProject)
include(mitkFunctionGenerateProjectXml)
include(mitkFunctionSuppressWarnings)
include(mitkFunctionEnableBuildConfiguration)
include(FeatureSummary)
SUPPRESS_VC_DEPRECATED_WARNINGS()
#-----------------------------------------------------------------------------
# Output directories.
#-----------------------------------------------------------------------------
foreach(type LIBRARY RUNTIME ARCHIVE)
# Make sure the directory exists
if(DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY
AND NOT EXISTS ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY})
message("Creating directory MITK_CMAKE_${type}_OUTPUT_DIRECTORY: ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}")
file(MAKE_DIRECTORY "${MITK_CMAKE_${type}_OUTPUT_DIRECTORY}")
endif()
if(MITK_USE_SUPERBUILD)
set(output_dir ${MITK_BINARY_DIR}/bin)
if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY)
set(MITK_CMAKE_${type}_OUTPUT_DIRECTORY ${MITK_BINARY_DIR}/MITK-build/bin)
endif()
else()
if(NOT DEFINED MITK_CMAKE_${type}_OUTPUT_DIRECTORY)
set(output_dir ${MITK_BINARY_DIR}/bin)
else()
set(output_dir ${MITK_CMAKE_${type}_OUTPUT_DIRECTORY})
endif()
endif()
set(CMAKE_${type}_OUTPUT_DIRECTORY ${output_dir} CACHE INTERNAL "Single output directory for building all libraries.")
mark_as_advanced(CMAKE_${type}_OUTPUT_DIRECTORY)
endforeach()
#-----------------------------------------------------------------------------
# Additional MITK Options (also shown during superbuild)
#-----------------------------------------------------------------------------
option(BUILD_SHARED_LIBS "Build MITK with shared libraries" ON)
option(WITH_COVERAGE "Enable/Disable coverage" OFF)
option(BUILD_TESTING "Test the project" ON)
macro(env_option name doc value)
set(_value $ENV{${name}})
if("${_value}" STREQUAL "")
set(_value ${value})
endif()
option(${name} "${doc}" ${_value})
endmacro()
# -----------------------------------------
# Qt version related variables
env_option(MITK_USE_QT "Use Nokia's Qt library" ON)
set(MITK_DESIRED_QT_VERSION ${DESIRED_QT_VERSION})
if(MITK_USE_QT)
# find the package at the very beginning, so that QT4_FOUND is available
if(DESIRED_QT_VERSION MATCHES 4)
set(MITK_QT4_MINIMUM_VERSION 4.7)
find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED)
set(MITK_USE_Qt4 TRUE)
set(MITK_USE_Qt5 FALSE)
endif()
if(DESIRED_QT_VERSION MATCHES 5)
set(MITK_QT5_MINIMUM_VERSION 5.0.0)
set(MITK_USE_Qt4 FALSE)
set(MITK_USE_Qt5 TRUE)
set(QT5_INSTALL_PREFIX "" CACHE PATH "The install location of Qt5")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_INSTALL_PREFIX})
find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
endif()
else()
set(MITK_USE_Qt4 FALSE)
set(MITK_USE_Qt5 FALSE)
endif()
# -----------------------------------------
# MITK_USE_* build variables
env_option(MITK_BUILD_ALL_APPS "Build all MITK applications" OFF)
set(MITK_BUILD_TUTORIAL OFF CACHE INTERNAL "Deprecated! Use MITK_BUILD_EXAMPLES instead!")
env_option(MITK_BUILD_EXAMPLES "Build the MITK Examples" ${MITK_BUILD_TUTORIAL})
env_option(MITK_USE_ACVD "Use Approximated Centroidal Voronoi Diagrams" OFF)
env_option(MITK_USE_CppUnit "Use CppUnit for unit tests" ON)
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()
env_option(MITK_USE_GLEW "Use the GLEW library" ON)
env_option(MITK_USE_Boost "Use the Boost C++ library" OFF)
env_option(MITK_USE_BLUEBERRY "Build the BlueBerry platform" ${MITK_USE_Qt4})
env_option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_Qt4})
env_option(MITK_USE_DCMTK "EXPERIMENTAL, superbuild only: Use DCMTK in MITK" ${MITK_USE_CTK})
env_option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF)
env_option(MITK_USE_OpenCL "Use OpenCL GPU-Computing library" OFF)
env_option(MITK_USE_Poco "Use the Poco library" ON)
env_option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF)
env_option(MITK_USE_Python "Use Python wrapping in MITK" OFF)
+env_option(MITK_USE_SimpleITK "Use the SimpleITK library" OFF)
set(MITK_USE_CableSwig ${MITK_USE_Python})
option(MITK_ENABLE_PIC_READER "Enable support for reading the DKFZ pic file format." ON)
set(MITK_BUILD_CONFIGURATION "Custom" CACHE STRING "Use pre-defined MITK configurations")
set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS Custom Default All)
mitkFunctionEnableBuildConfiguration()
mark_as_advanced(MITK_BUILD_ALL_APPS
MITK_USE_CppUnit
MITK_USE_GLEW
MITK_USE_CTK
MITK_USE_DCMTK
MITK_ENABLE_PIC_READER
MITK_BUILD_CONFIGURATION
)
if(MITK_USE_Python)
- FIND_PACKAGE(PythonLibs REQUIRED)
- FIND_PACKAGE(PythonInterp REQUIRED)
+ if(APPLE)
+ message(WARNING "Python wrapping is unsuported on mac OSX!")
+ set(MITK_USE_Python OFF CACHE BOOL "Use Python wrapping in MITK" FORCE)
+ else()
+ option(MITK_USE_SYSTEM_PYTHON "Use the system python runtime" OFF)
+ # SimpleITK is required when python is enabled
+ set(MITK_USE_SimpleITK ON CACHE BOOL "Use the SimpleITK library" FORCE)
+ if(MITK_USE_SYSTEM_PYTHON)
+ FIND_PACKAGE(PythonLibs REQUIRED)
+ FIND_PACKAGE(PythonInterp REQUIRED)
+ else()
+ FIND_PACKAGE(PythonLibs)
+ FIND_PACKAGE(PythonInterp)
+ endif()
+ endif()
endif()
if(MITK_USE_Boost)
option(MITK_USE_SYSTEM_Boost "Use the system Boost" OFF)
set(MITK_USE_Boost_LIBRARIES "" CACHE STRING "A semi-colon separated list of required Boost libraries")
endif()
if(MITK_USE_BLUEBERRY AND NOT MITK_USE_Qt4)
message("> Forcing MITK_USE_BLUEBERRY to OFF because Qt4 is not used.")
set(MITK_USE_BLUEBERRY OFF CACHE BOOL "Build the BlueBerry application platform" FORCE)
endif()
if(MITK_USE_CTK AND NOT MITK_USE_Qt4)
message("> Forcing MITK_USE_CTK to OFF because Qt4 is not used.")
set(MITK_USE_CTK OFF CACHE BOOL "Use CTK in MITK" 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()
if(MITK_USE_CTK AND NOT MITK_USE_DCMTK)
message("> Forcing MITK_USE_DCMTK to ON because of MITK_USE_CTK")
set(MITK_USE_DCMTK ON CACHE BOOL "Use DCMTK in MITK" FORCE)
endif()
if(MITK_USE_SOFA)
# SOFA requires at least CMake 2.8.8
set(SOFA_CMAKE_VERSION 2.8.8)
if(${CMAKE_VERSION} VERSION_LESS ${SOFA_CMAKE_VERSION})
set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE)
message(WARNING "Switched off MITK_USE_SOFA\n Minimum required CMake version: ${SOFA_CMAKE_VERSION}\n Installed CMake version: ${CMAKE_VERSION}")
endif()
# SOFA/ITK combination requires at least MSVC 2010
if(MSVC_VERSION AND MSVC_VERSION LESS 1600)
set(MITK_USE_SOFA OFF CACHE BOOL "" FORCE)
message(WARNING "Switched off MITK_USE_SOFA\n MSVC versions less than 2010 are not supported.")
endif()
# SOFA requires boost library
if(MITK_USE_SOFA AND NOT MITK_USE_Boost)
message("Forcing MITK_USE_Boost to ON because of MITK_USE_SOFA")
set(MITK_USE_Boost ON CACHE BOOL "" FORCE)
endif()
# SOFA requires boost system library
list(FIND MITK_USE_Boost_LIBRARIES system _result)
if(_result LESS 0)
message("Adding 'system' to MITK_USE_Boost_LIBRARIES.")
list(APPEND MITK_USE_Boost_LIBRARIES system)
endif()
# SOFA requires boost thread library
list(FIND MITK_USE_Boost_LIBRARIES thread _result)
if(_result LESS 0)
message("Adding 'thread' to MITK_USE_Boost_LIBRARIES.")
list(APPEND MITK_USE_Boost_LIBRARIES thread)
endif()
set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "" FORCE)
# Allow setting external SOFA plugins directory and SOFA plugins
set(MITK_USE_SOFA_PLUGINS_DIR ${MITK_USE_SOFA_PLUGINS_DIR} CACHE PATH "External SOFA plugins directory" FORCE)
set(MITK_USE_SOFA_PLUGINS ${MITK_USE_SOFA_PLUGINS} CACHE PATH "List of semicolon-separated plugin names" FORCE)
endif()
# 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)
if(MITK_USE_BLUEBERRY)
list(APPEND CTEST_PROJECT_SUBPROJECTS BlueBerry)
endif()
list(APPEND CTEST_PROJECT_SUBPROJECTS
MITK-Core
MITK-CoreUI
MITK-IGT
MITK-ToF
MITK-DTI
MITK-Registration
MITK-Modules # all modules not contained in a specific subproject
MITK-Plugins # all plugins not contained in a specific subproject
MITK-Examples
Unlabeled # special "subproject" catching all unlabeled targets and tests
)
# Configure CTestConfigSubProject.cmake that could be used by CTest scripts
configure_file(${MITK_SOURCE_DIR}/CTestConfigSubProject.cmake.in
${MITK_BINARY_DIR}/CTestConfigSubProject.cmake)
if(CTEST_PROJECT_ADDITIONAL_TARGETS)
# those targets will be executed at the end of the ctest driver script
# and they also get their own subproject label
set(subproject_list "${CTEST_PROJECT_SUBPROJECTS};${CTEST_PROJECT_ADDITIONAL_TARGETS}")
else()
set(subproject_list "${CTEST_PROJECT_SUBPROJECTS}")
endif()
# Generate Project.xml file expected by the CTest driver script
mitkFunctionGenerateProjectXml(${MITK_BINARY_DIR} MITK "${subproject_list}" ${MITK_USE_SUPERBUILD})
#-----------------------------------------------------------------------------
# Superbuild script
#-----------------------------------------------------------------------------
if(MITK_USE_SUPERBUILD)
include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake")
# 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(mitkFunctionCheckCompilerFlags)
include(mitkFunctionGetGccVersion)
include(MacroParseArguments)
include(mitkFunctionSuppressWarnings) # includes several functions
include(mitkFunctionOrganizeSources)
include(mitkFunctionGetVersion)
include(mitkFunctionGetVersionDescription)
include(mitkFunctionCreateWindowsBatchScript)
include(mitkFunctionInstallProvisioningFiles)
include(mitkFunctionInstallAutoLoadModules)
include(mitkFunctionGetLibrarySearchPaths)
include(mitkFunctionCompileSnippets)
include(mitkFunctionUseModules)
include(mitkMacroCreateModuleConf)
include(mitkFunctionCheckModuleDependencies)
include(mitkFunctionCreateModule)
include(mitkMacroCreateExecutable)
include(mitkMacroCheckModule)
include(mitkMacroCreateModuleTests)
include(mitkFunctionAddCustomModuleTest)
include(mitkMacroUseModule)
include(mitkMacroMultiplexPicType)
include(mitkMacroInstall)
include(mitkMacroInstallHelperApp)
include(mitkMacroInstallTargets)
include(mitkMacroGenerateToolsLibrary)
include(mitkMacroGetLinuxDistribution)
include(mitkMacroGetPMDPlatformString)
#-----------------------------------------------------------------------------
# Set MITK specific options and variables (NOT available during superbuild)
#-----------------------------------------------------------------------------
# ASK THE USER TO SHOW THE CONSOLE WINDOW FOR CoreApp and mitkWorkbench
option(MITK_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting MITK GUI Applications" ON)
mark_as_advanced(MITK_SHOW_CONSOLE_WINDOW)
# TODO: check if necessary
option(USE_ITKZLIB "Use the ITK zlib for pic compression." ON)
mark_as_advanced(USE_ITKZLIB)
if(NOT MITK_FAST_TESTING)
if(DEFINED MITK_CTEST_SCRIPT_MODE
AND (MITK_CTEST_SCRIPT_MODE STREQUAL "continuous" OR MITK_CTEST_SCRIPT_MODE STREQUAL "experimental") )
set(MITK_FAST_TESTING 1)
endif()
endif()
#-----------------------------------------------------------------------------
# Get MITK version info
#-----------------------------------------------------------------------------
mitkFunctionGetVersion(${MITK_SOURCE_DIR} MITK)
mitkFunctionGetVersionDescription(${MITK_SOURCE_DIR} MITK)
#-----------------------------------------------------------------------------
# Installation preparation
#
# These should be set before any MITK install macros are used
#-----------------------------------------------------------------------------
# on Mac OSX all BlueBerry plugins get copied into every
# application bundle (.app directory) specified here
if(MITK_USE_BLUEBERRY AND APPLE)
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake")
foreach(mitk_app ${MITK_APPS})
# extract option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 1 option_name)
list(GET target_info_list 0 app_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
set(MACOSX_BUNDLE_NAMES ${MACOSX_BUNDLE_NAMES} Mitk${app_name})
endif()
endforeach()
endif()
#-----------------------------------------------------------------------------
# Set symbol visibility Flags
#-----------------------------------------------------------------------------
# MinGW does not export all symbols automatically, so no need to set flags
if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
set(VISIBILITY_CXX_FLAGS ) #"-fvisibility=hidden -fvisibility-inlines-hidden")
endif()
#-----------------------------------------------------------------------------
# Set coverage Flags
#-----------------------------------------------------------------------------
if(WITH_COVERAGE)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG")
set(COVERAGE_CXX_FLAGS ${coverage_flags})
set(COVERAGE_C_FLAGS ${coverage_flags})
endif()
endif()
#-----------------------------------------------------------------------------
# MITK C/CXX Flags
#-----------------------------------------------------------------------------
set(MITK_C_FLAGS "${COVERAGE_C_FLAGS}")
set(MITK_C_FLAGS_DEBUG )
set(MITK_C_FLAGS_RELEASE )
set(MITK_CXX_FLAGS "${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}")
set(MITK_CXX_FLAGS_DEBUG )
set(MITK_CXX_FLAGS_RELEASE )
set(MITK_EXE_LINKER_FLAGS )
set(MITK_SHARED_LINKER_FLAGS )
if(WIN32)
set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN")
set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} /wd4231") # 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
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
# the following two lines should be removed after ITK-3097 has
# been resolved, see also MITK bug 15279
-Wno-unused-local-typedefs
-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)
mitkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION)
# With older version of gcc supporting the flag -fstack-protector-all, an extra dependency to libssp.so
# is introduced. If gcc is smaller than 4.4.0 and the build type is Release let's not include the flag.
# Doing so should allow to build package made for distribution using older linux distro.
if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0"))
mitkFunctionCheckCAndCXXCompilerFlags("-fstack-protector-all" MITK_C_FLAGS MITK_CXX_FLAGS)
endif()
if(MINGW)
# suppress warnings about auto imported symbols
set(MITK_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import ${MITK_SHARED_LINKER_FLAGS}")
endif()
set(MITK_CXX_FLAGS_RELEASE "-D_FORTIFY_SOURCE=2 ${MITK_CXX_FLAGS_RELEASE}")
endif()
set(MITK_MODULE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS})
set(MITK_EXE_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS})
#-----------------------------------------------------------------------------
# MITK Packages
#-----------------------------------------------------------------------------
set(MITK_MODULES_PACKAGE_DEPENDS_DIR ${MITK_SOURCE_DIR}/CMake/PackageDepends)
set(MODULES_PACKAGE_DEPENDS_DIRS ${MITK_MODULES_PACKAGE_DEPENDS_DIR})
#-----------------------------------------------------------------------------
# Testing
#-----------------------------------------------------------------------------
if(BUILD_TESTING)
enable_testing()
include(CTest)
mark_as_advanced(TCL_TCLSH DART_ROOT)
option(MITK_ENABLE_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
)
# Configuration for the CMake-generated test driver
set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include ")
set(CMAKE_TESTDRIVER_BEFORE_TESTMAIN "
try
{")
set(CMAKE_TESTDRIVER_AFTER_TESTMAIN " }
catch( std::exception & excp )
{
fprintf(stderr,\"%s\\n\",excp.what());
return EXIT_FAILURE;
}
catch( ... )
{
printf(\"Exception caught in the test driver\\n\");
return EXIT_FAILURE;
}
")
set(MITK_TEST_OUTPUT_DIR "${MITK_BINARY_DIR}/test_output")
if(NOT EXISTS ${MITK_TEST_OUTPUT_DIR})
file(MAKE_DIRECTORY ${MITK_TEST_OUTPUT_DIR})
endif()
# Test the external project template
if(MITK_USE_BLUEBERRY)
include(mitkTestProjectTemplate)
endif()
# Test the package target
include(mitkPackageTest)
endif()
configure_file(mitkTestingConfig.h.in ${MITK_BINARY_DIR}/mitkTestingConfig.h)
#-----------------------------------------------------------------------------
# MITK_SUPERBUILD_BINARY_DIR
#-----------------------------------------------------------------------------
# If MITK_SUPERBUILD_BINARY_DIR isn't defined, it means MITK is *NOT* build using Superbuild.
# In that specific case, MITK_SUPERBUILD_BINARY_DIR should default to MITK_BINARY_DIR
if(NOT DEFINED MITK_SUPERBUILD_BINARY_DIR)
set(MITK_SUPERBUILD_BINARY_DIR ${MITK_BINARY_DIR})
endif()
#-----------------------------------------------------------------------------
# Compile Utilities and set-up MITK variables
#-----------------------------------------------------------------------------
include(mitkSetupVariables)
#-----------------------------------------------------------------------------
# Cleanup
#-----------------------------------------------------------------------------
file(GLOB _MODULES_CONF_FILES ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake)
if(_MODULES_CONF_FILES)
file(REMOVE ${_MODULES_CONF_FILES})
endif()
add_subdirectory(Utilities)
if(MITK_USE_BLUEBERRY)
# We need to hack a little bit because MITK applications may need
# to enable certain BlueBerry plug-ins. However, these plug-ins
# are validated separately from the MITK plug-ins and know nothing
# about potential MITK plug-in dependencies of the applications. Hence
# we cannot pass the MITK application list to the BlueBerry
# ctkMacroSetupPlugins call but need to extract the BlueBerry dependencies
# from the applications and set them explicitly.
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/AppList.cmake")
foreach(mitk_app ${MITK_APPS})
# extract target_dir and option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 0 target_dir)
list(GET target_info_list 1 option_name)
# check if the application is enabled and if target_libraries.cmake exists
if((${option_name} OR MITK_BUILD_ALL_APPS) AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/target_libraries.cmake")
foreach(_target_dep ${target_libraries})
if(_target_dep MATCHES org_blueberry_)
string(REPLACE _ . _app_bb_dep ${_target_dep})
# explicitly set the build option for the BlueBerry plug-in
set(BLUEBERRY_BUILD_${_app_bb_dep} ON CACHE BOOL "Build the ${_app_bb_dep} plug-in")
endif()
endforeach()
endif()
endforeach()
set(mbilog_DIR "${mbilog_BINARY_DIR}")
if(MITK_BUILD_ALL_PLUGINS)
set(BLUEBERRY_BUILD_ALL_PLUGINS ON)
endif()
set(BLUEBERRY_XPDOC_OUTPUT_DIR ${MITK_DOXYGEN_OUTPUT_DIR}/html/extension-points/html/)
add_subdirectory(BlueBerry)
set(BlueBerry_DIR ${CMAKE_CURRENT_BINARY_DIR}/BlueBerry
CACHE PATH "The directory containing a CMake configuration file for BlueBerry" FORCE)
include(mitkMacroCreateCTKPlugin)
endif()
#-----------------------------------------------------------------------------
# Set C/CXX and linker flags for MITK code
#-----------------------------------------------------------------------------
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MITK_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MITK_CXX_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MITK_CXX_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MITK_C_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${MITK_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${MITK_C_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MITK_EXE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${MITK_SHARED_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${MITK_MODULE_LINKER_FLAGS}")
#-----------------------------------------------------------------------------
# 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(Core)
add_subdirectory(Modules)
if(MITK_USE_BLUEBERRY)
find_package(BlueBerry REQUIRED)
set(MITK_DEFAULT_SUBPROJECTS MITK-Plugins)
# Plug-in testing (needs some work to be enabled again)
if(BUILD_TESTING)
include(berryTestingHelpers)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp")
get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE)
if(APPLE AND _is_macosx_bundle)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp")
endif()
set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication")
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake")
set(mitk_plugins_fullpath )
foreach(mitk_plugin ${MITK_EXT_PLUGINS})
list(APPEND mitk_plugins_fullpath Plugins/${mitk_plugin})
endforeach()
if(EXISTS ${MITK_PRIVATE_MODULES}/PluginList.cmake)
include(${MITK_PRIVATE_MODULES}/PluginList.cmake)
foreach(mitk_plugin ${MITK_PRIVATE_PLUGINS})
list(APPEND mitk_plugins_fullpath ${MITK_PRIVATE_MODULES}/${mitk_plugin})
endforeach()
endif()
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})
list(APPEND mitk_apps_fullpath "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${mitk_app}")
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()
# 11.3.13, change, muellerm: activate python bundle if python and blueberry is active
if( MITK_USE_Python )
set(MITK_BUILD_org.mitk.gui.qt.python ON)
endif()
endif()
-#-----------------------------------------------------------------------------
-# Python Wrapping
-#-----------------------------------------------------------------------------
-option(MITK_USE_Python "Build Python integration for MITK (requires CableSwig)." OFF)
-
#-----------------------------------------------------------------------------
# Documentation
#-----------------------------------------------------------------------------
add_subdirectory(Documentation)
#-----------------------------------------------------------------------------
# Installation
#-----------------------------------------------------------------------------
# set MITK cpack variables
# These are the default variables, which can be overwritten ( see below )
include(mitkSetupCPack)
set(use_default_config ON)
# MITK_APPS is set in Applications/AppList.cmake (included somewhere above
# if MITK_USE_BLUEBERRY is set to ON).
if(MITK_APPS)
set(activated_apps_no 0)
list(LENGTH MITK_APPS app_count)
# Check how many apps have been enabled
# If more than one app has been activated, the we use the
# default CPack configuration. Otherwise that apps configuration
# will be used, if present.
foreach(mitk_app ${MITK_APPS})
# extract option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 1 option_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
MATH(EXPR activated_apps_no "${activated_apps_no} + 1")
endif()
endforeach()
if(app_count EQUAL 1 AND (activated_apps_no EQUAL 1 OR MITK_BUILD_ALL_APPS))
# Corner case if there is only one app in total
set(use_project_cpack ON)
elseif(activated_apps_no EQUAL 1 AND NOT MITK_BUILD_ALL_APPS)
# Only one app is enabled (no "build all" flag set)
set(use_project_cpack ON)
else()
# Less or more then one app is enabled
set(use_project_cpack OFF)
endif()
foreach(mitk_app ${MITK_APPS})
# extract target_dir and option_name
string(REPLACE "^^" "\\;" target_info ${mitk_app})
set(target_info_list ${target_info})
list(GET target_info_list 0 target_dir)
list(GET target_info_list 1 option_name)
# check if the application is enabled
if(${option_name} OR MITK_BUILD_ALL_APPS)
# check whether application specific configuration files will be used
if(use_project_cpack)
# use files if they exist
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/Applications/${target_dir}/CPackOptions.cmake")
endif()
if(EXISTS "${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in")
set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/Applications/${target_dir}/CPackConfig.cmake")
configure_file(${PROJECT_SOURCE_DIR}/Applications/${target_dir}/CPackConfig.cmake.in
${CPACK_PROJECT_CONFIG_FILE} @ONLY)
set(use_default_config OFF)
endif()
endif()
# add link to the list
list(APPEND CPACK_CREATE_DESKTOP_LINKS "${target_dir}")
endif()
endforeach()
endif()
# if no application specific configuration file was used, use default
if(use_default_config)
configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in
${MITK_BINARY_DIR}/MITKCPackOptions.cmake @ONLY)
set(CPACK_PROJECT_CONFIG_FILE "${MITK_BINARY_DIR}/MITKCPackOptions.cmake")
endif()
# include CPack model once all variables are set
include(CPack)
# Additional installation rules
include(mitkInstallRules)
#-----------------------------------------------------------------------------
# Last configuration steps
#-----------------------------------------------------------------------------
set(MITK_EXPORTS_FILE "${MITK_BINARY_DIR}/MitkExports.cmake")
file(REMOVE ${MITK_EXPORTS_FILE})
set(targets_to_export)
get_property(module_targets GLOBAL PROPERTY MITK_MODULE_TARGETS)
if(module_targets)
list(APPEND targets_to_export ${module_targets})
endif()
if(MITK_USE_BLUEBERRY)
if(MITK_PLUGIN_LIBRARIES)
list(APPEND targets_to_export ${MITK_PLUGIN_LIBRARIES})
endif()
endif()
export(TARGETS ${targets_to_export} APPEND
FILE ${MITK_EXPORTS_FILE})
set(MITK_EXPORTED_TARGET_PROPERTIES )
foreach(target_to_export ${targets_to_export})
get_target_property(autoload_targets ${target_to_export} MITK_AUTOLOAD_TARGETS)
if(autoload_targets)
set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES}
set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_TARGETS \"${autoload_targets}\")")
endif()
get_target_property(autoload_dir ${target_to_export} MITK_AUTOLOAD_DIRECTORY)
if(autoload_dir)
set(MITK_EXPORTED_TARGET_PROPERTIES "${MITK_EXPORTED_TARGET_PROPERTIES}
set_target_properties(${target_to_export} PROPERTIES MITK_AUTOLOAD_DIRECTORY \"${autoload_dir}\")")
endif()
endforeach()
get_property(MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS_CONFIG GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactory.cpp.in
${MITK_BINARY_DIR}/ToolExtensionITKFactory.cpp.in COPYONLY)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolExtensionITKFactoryLoader.cpp.in
${MITK_BINARY_DIR}/ToolExtensionITKFactoryLoader.cpp.in COPYONLY)
configure_file(${MITK_SOURCE_DIR}/CMake/ToolGUIExtensionITKFactory.cpp.in
${MITK_BINARY_DIR}/ToolGUIExtensionITKFactory.cpp.in COPYONLY)
set(VISIBILITY_AVAILABLE 0)
set(visibility_test_flag "")
mitkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_test_flag)
if(visibility_test_flag)
# The compiler understands -fvisiblity=hidden (probably gcc >= 4 or Clang)
set(VISIBILITY_AVAILABLE 1)
endif()
configure_file(mitkExportMacros.h.in ${MITK_BINARY_DIR}/mitkExportMacros.h)
configure_file(mitkVersion.h.in ${MITK_BINARY_DIR}/mitkVersion.h)
configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h)
set(IPFUNC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/ipFunc)
set(UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities)
file(GLOB _MODULES_CONF_FILES RELATIVE ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME} ${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}/*.cmake)
set(MITK_MODULE_NAMES)
foreach(_module ${_MODULES_CONF_FILES})
string(REPLACE Config.cmake "" _module_name ${_module})
list(APPEND MITK_MODULE_NAMES ${_module_name})
endforeach()
configure_file(mitkConfig.h.in ${MITK_BINARY_DIR}/mitkConfig.h)
configure_file(MITKConfig.cmake.in ${MITK_BINARY_DIR}/MITKConfig.cmake @ONLY)
write_basic_config_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${MITK_VERSION_STRING} COMPATIBILITY AnyNewerVersion)
# If we are under Windows, create two batch files which correctly
# set up the environment for the application and for Visual Studio
if(WIN32)
include(mitkFunctionCreateWindowsBatchScript)
set(VS_SOLUTION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.sln")
foreach(VS_BUILD_TYPE debug release)
mitkFunctionCreateWindowsBatchScript("${MITK_SOURCE_DIR}/CMake/StartVS.bat.in"
${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat
${VS_BUILD_TYPE})
endforeach()
endif(WIN32)
#-----------------------------------------------------------------------------
# MITK Applications
#-----------------------------------------------------------------------------
# This must come after MITKConfig.h was generated, since applications
# might do a find_package(MITK REQUIRED).
add_subdirectory(Applications)
#-----------------------------------------------------------------------------
# MITK Examples
#-----------------------------------------------------------------------------
if(MITK_BUILD_EXAMPLES)
# This must come after MITKConfig.h was generated, since applications
# might do a find_package(MITK REQUIRED).
add_subdirectory(Examples)
endif()
#-----------------------------------------------------------------------------
# Print configuration summary
#-----------------------------------------------------------------------------
message("\n\n")
feature_summary(
DESCRIPTION "------- FEATURE SUMMARY FOR ${PROJECT_NAME} -------"
WHAT ALL
)
+
diff --git a/MITKConfig.cmake.in b/MITKConfig.cmake.in
index d4c40e210a..04a6c39106 100644
--- a/MITKConfig.cmake.in
+++ b/MITKConfig.cmake.in
@@ -1,201 +1,203 @@
# Update the CMake module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "@MITK_SOURCE_DIR@/CMake")
set(CppMicroServices_DIR "@MITK_BINARY_DIR@/Core/CppMicroServices")
# Include MITK macros
include(MacroParseArguments)
include(mitkFunctionCheckMitkCompatibility)
include(mitkFunctionOrganizeSources)
include(mitkFunctionCreateWindowsBatchScript)
include(mitkFunctionInstallProvisioningFiles)
include(mitkFunctionInstallAutoLoadModules)
include(mitkFunctionGetLibrarySearchPaths)
include(mitkFunctionUseModules)
include(mitkMacroCreateModuleConf)
include(mitkFunctionCheckModuleDependencies)
include(mitkFunctionCreateModule)
include(mitkMacroCreateExecutable)
include(mitkMacroCheckModule)
include(mitkMacroCreateModuleTests)
include(mitkFunctionAddCustomModuleTest)
include(mitkMacroUseModule)
include(mitkMacroMultiplexPicType)
include(mitkMacroInstall)
include(mitkMacroInstallHelperApp)
include(mitkMacroInstallTargets)
include(mitkMacroGenerateToolsLibrary)
include(mitkMacroCreateCTKPlugin)
include(mitkMacroGetPMDPlatformString)
# Standard CMake macros
include(FeatureSummary)
# The MITK version number
set(MITK_VERSION_MAJOR "@MITK_VERSION_MAJOR@")
set(MITK_VERSION_MINOR "@MITK_VERSION_MINOR@")
set(MITK_VERSION_PATCH "@MITK_VERSION_PATCH@")
set(MITK_VERSION_STRING "@MITK_VERSION_STRING@")
# MITK compiler flags
set(MITK_C_FLAGS "@MITK_C_FLAGS@")
set(MTTK_C_FLAGS_DEBUG "@MITK_C_FLAGS_DEBUG@")
set(MITK_C_FLAGS_RELEASE "@MITK_C_FLAGS_RELEASE@")
set(MITK_CXX_FLAGS "@MITK_CXX_FLAGS@")
set(MTTK_CXX_FLAGS_DEBUG "@MITK_CXX_FLAGS_DEBUG@")
set(MITK_CXX_FLAGS_RELEASE "@MITK_CXX_FLAGS_RELEASE@")
set(MITK_EXE_LINKER_FLAGS "@MITK_EXE_LINKER_FLAGS@")
set(MITK_SHARED_LINKER_FLAGS "@MITK_SHARED_LINKER_FLAGS@")
set(MITK_MODULE_LINKER_FLAGS "@MITK_MODULE_LINKER_FLAGS@")
# Internal version numbers, used for approximate compatibility checks
# of a MITK development version (non-release).
set(MITK_VERSION_PLUGIN_SYSTEM 2) # dropped legacy BlueBerry plug-in CMake support
# MITK specific variables
set(MITK_SOURCE_DIR "@MITK_SOURCE_DIR@")
set(MITK_BINARY_DIR "@MITK_BINARY_DIR@")
set(MITK_CMAKE_DIR "@MITK_CMAKE_DIR@")
set(UTILITIES_DIR "@UTILITIES_DIR@")
set(REGISTER_QFUNCTIONALITY_CPP_IN "@REGISTER_QFUNCTIONALITY_CPP_IN@")
set(MITK_MODULES_PACKAGE_DEPENDS_DIR "@MITK_MODULES_PACKAGE_DEPENDS_DIR@")
set(MODULES_PACKAGE_DEPENDS_DIRS "@MODULES_PACKAGE_DEPENDS_DIRS@")
set(MITK_DOXYGEN_TAGFILE_NAME "@MITK_DOXYGEN_TAGFILE_NAME@")
if(MODULES_CONF_DIRS)
list(APPEND MODULES_CONF_DIRS "@MODULES_CONF_DIRS@")
list(REMOVE_DUPLICATES MODULES_CONF_DIRS)
else()
set(MODULES_CONF_DIRS "@MODULES_CONF_DIRS@")
endif()
set(MODULES_CONF_DIRNAME "@MODULES_CONF_DIRNAME@")
foreach(_module @MITK_MODULE_NAMES@)
set(${_module}_CONFIG_FILE "@MITK_BINARY_DIR@/@MODULES_CONF_DIRNAME@/${_module}Config.cmake")
endforeach()
# External projects
set(CTK_DIR "@CTK_DIR@")
set(ANN_DIR "@ANN_DIR@")
set(CppUnit_DIR "@CppUnit_DIR@")
set(GLEW_DIR "@GLEW_DIR@")
set(tinyxml_DIR "@tinyxml_DIR@")
set(ITK_DIR "@ITK_DIR@")
set(VTK_DIR "@VTK_DIR@")
set(DCMTK_DIR "@DCMTK_DIR@")
set(GDCM_DIR "@GDCM_DIR@")
set(BOOST_ROOT "@BOOST_ROOT@")
set(OpenCV_DIR "@OpenCV_DIR@")
set(Poco_DIR "@Poco_DIR@")
set(SOFA_DIR "@SOFA_DIR@")
set(Qwt_DIR "@Qwt_DIR@")
set(Qxt_DIR "@Qxt_DIR@")
set(ACVD_DIR "@ACVD_DIR@")
set(MITK_QMAKE_EXECUTABLE "@QT_QMAKE_EXECUTABLE@")
set(MITK_DATA_DIR "@MITK_DATA_DIR@")
+set(SimpleITK_DIR "@SimpleITK_DIR@")
# External SDK directories
set(MITK_PMD_SDK_DIR @MITK_PMD_SDK_DIR@)
# MITK use variables
set(MITK_USE_QT @MITK_USE_QT@)
set(MITK_USE_Qt4 @MITK_USE_Qt4@)
set(MITK_USE_Qt5 @MITK_USE_Qt5@)
set(MITK_DESIRED_QT_VERSION @DESIRED_QT_VERSION@)
set(MITK_USE_BLUEBERRY @MITK_USE_BLUEBERRY@)
set(MITK_USE_SYSTEM_Boost @MITK_USE_SYSTEM_Boost@)
set(MITK_USE_Boost @MITK_USE_Boost@)
set(MITK_USE_Boost_LIBRARIES @MITK_USE_Boost_LIBRARIES@)
set(MITK_USE_CTK @MITK_USE_CTK@)
set(MITK_USE_DCMTK @MITK_USE_DCMTK@)
set(MITK_USE_OpenCV @MITK_USE_OpenCV@)
set(MITK_USE_SOFA @MITK_USE_SOFA@)
set(MITK_USE_Python @MITK_USE_Python@)
+set(MITK_USE_SimpleITK @MITK_USE_SimpleITK@)
set(MITK_USE_ACVD @MITK_USE_ACVD@)
if(MITK_USE_Qt4)
set(MITK_QT4_MINIMUM_VERSION @MITK_QT4_MINIMUM_VERSION@)
find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED)
elseif(MITK_USE_Qt5)
set(MITK_QT5_MINIMUM_VERSION @MITK_QT5_MINIMUM_VERSION@)
find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
endif()
# MITK ToF use variables
set(MITK_TOF_PMDCAMCUBE_AVAILABLE @MITK_USE_TOF_PMDCAMCUBE@)
if(MITK_TOF_PMDCAMCUBE_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDCAMCUBE "Enable support for PMD Cam Cube" @MITK_USE_TOF_PMDCAMCUBE@)
mark_as_advanced(MITK_USE_TOF_PMDCAMCUBE)
endif()
set(MITK_TOF_PMDCAMBOARD_AVAILABLE @MITK_USE_TOF_PMDCAMBOARD@)
if(MITK_TOF_PMDCAMBOARD_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDCAMBOARD "Enable support for PMD Cam Board" @MITK_USE_TOF_PMDCAMBOARD@)
mark_as_advanced(MITK_USE_TOF_PMDCAMBOARD)
endif()
set(MITK_TOF_PMDO3_AVAILABLE @MITK_USE_TOF_PMDO3@)
if(MITK_TOF_PMDO3_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_PMDO3 "Enable support for PMD =3" @MITK_USE_TOF_PMDO3@)
mark_as_advanced(MITK_USE_TOF_PMDO3)
endif()
set(MITK_TOF_KINECT_AVAILABLE @MITK_USE_TOF_KINECT@)
if(MITK_TOF_KINECT_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_KINECT "Enable support for Kinect" @MITK_USE_TOF_KINECT@)
mark_as_advanced(MITK_USE_TOF_KINECT)
endif()
set(MITK_TOF_MESASR4000_AVAILABLE @MITK_USE_TOF_MESASR4000@)
if(MITK_TOF_MESASR4000_AVAILABLE AND NOT ${PROJECT_NAME} STREQUAL "MITK")
option(MITK_USE_TOF_MESASR4000 "Enable support for MESA SR4000" @MITK_USE_TOF_MESASR4000@)
mark_as_advanced(MITK_USE_TOF_MESASR4000)
endif()
if(MITK_USE_IGT)
#include("${MITK_DIR}/mitkIGTConfig.cmake")
endif()
# Install rules for ToF libraries loaded at runtime
include("@MITK_BINARY_DIR@/mitkToFHardwareInstallRules.cmake")
if(NOT MITK_EXPORTS_FILE_INCLUDED)
if(EXISTS "@MITK_EXPORTS_FILE@")
set(MITK_EXPORTS_FILE_INCLUDED 1)
include("@MITK_EXPORTS_FILE@")
endif()
endif()
# BlueBerry support
if(MITK_USE_BLUEBERRY)
set(BlueBerry_DIR "@MITK_BINARY_DIR@/BlueBerry")
# Don't include the BlueBerry exports file, since the targets are
# also exported in the MITK exports file
set(BB_PLUGIN_EXPORTS_FILE_INCLUDED 1)
find_package(BlueBerry)
if(NOT BlueBerry_FOUND)
message(SEND_ERROR "MITK does not seem to be configured with BlueBerry support. Set MITK_USE_BLUEBERRY to ON in your MITK build configuration.")
endif()
set(MITK_PLUGIN_USE_FILE "@MITK_PLUGIN_USE_FILE@")
if(MITK_PLUGIN_USE_FILE)
if(EXISTS "${MITK_PLUGIN_USE_FILE}")
include("${MITK_PLUGIN_USE_FILE}")
endif()
endif()
set(MITK_PLUGIN_PROVISIONING_FILE "@MITK_EXTAPP_PROVISIONING_FILE@")
set(MITK_PROVISIONING_FILES
"${BLUEBERRY_PLUGIN_PROVISIONING_FILE}"
"${MITK_PLUGIN_PROVISIONING_FILE}")
endif()
# Set properties on exported targets
@MITK_EXPORTED_TARGET_PROPERTIES@
diff --git a/Modules/Python/CMakeLists.txt b/Modules/Python/CMakeLists.txt
index 475bb4d8bf..3025dd6481 100644
--- a/Modules/Python/CMakeLists.txt
+++ b/Modules/Python/CMakeLists.txt
@@ -1,12 +1,26 @@
if( MITK_USE_Python )
+ if(NOT MITK_USE_SYSTEM_PYTHON)
+ add_definitions( -DUSE_MITK_BUILTIN_PYTHON )
+ endif()
+
+ set(OpenCV_DEP )
+ if(MITK_USE_OpenCV)
+ set(OpenCV_DEP OpenCV)
+ endif()
+
+ # workaround until testing has a package depends
+ set(SimpleITK_DEP )
+ if(BUILD_TESTING AND NOT APPLE)
+ set(SimpleITK_DEP SimpleITK)
+ endif()
+
MITK_CREATE_MODULE(
DEPENDS MitkCore
EXPORT_DEFINE MITK_PYTHON_EXPORT
- PACKAGE_DEPENDS Qt4|QtGui CTK PythonLibs
+ PACKAGE_DEPENDS Qt4|QtGui CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP}
)
- configure_file(PythonPath.h.in
- "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY)
+ configure_file(PythonPath.h.in "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY)
add_subdirectory(Testing)
endif()
diff --git a/Modules/Python/PythonPath.h.in b/Modules/Python/PythonPath.h.in
index 6f5daf2961..d62c631f5a 100644
--- a/Modules/Python/PythonPath.h.in
+++ b/Modules/Python/PythonPath.h.in
@@ -1,21 +1,19 @@
#ifdef _DEBUG
#define PYTHON_PATH_BUILD_TYPE "/Debug"
#else
#define PYTHON_PATH_BUILD_TYPE "/Release"
#endif
#define PYTHONPATH_COMMAND "import sys\n"\
-"sys.path.append('@ITK_LIBRARY_DIRS@')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/WrapITK/Python')\n"\
-"sys.path.append('@ITK_LIBRARY_DIRS@" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/WrapITK/Python" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@ITK_DIR@/Wrapping/Generators/Python')\n"\
-"sys.path.append('@ITK_DIR@/lib')\n"\
-"sys.path.append('@VTK_LIBRARY_DIRS@')\n"\
+"sys.path.append('@SimpleITK_DIR@/bin')\n"\
+"sys.path.append('@SimpleITK_DIR@/lib')\n"\
+"sys.path.append('@SimpleITK_DIR@/Wrapping')\n"\
"sys.path.append('@VTK_DIR@/Wrapping/Python')\n"\
+"sys.path.append('@VTK_DIR@/lib')\n"\
"sys.path.append('@VTK_DIR@/bin" PYTHON_PATH_BUILD_TYPE "')\n"\
-"sys.path.append('@VTK_DIR@/Wrapping/Python')\n"\
"sys.path.append('@OpenCV_DIR@/lib" PYTHON_PATH_BUILD_TYPE "')\n"\
"sys.path.append('@OpenCV_DIR@/lib')\n"\
"sys.path.append('@OpenCV_DIR@/bin')\n"\
"sys.path.append('@OpenCV_DIR@/bin" PYTHON_PATH_BUILD_TYPE "')"
+
+#define PYTHONHOME "@Python_DIR@"
diff --git a/Modules/Python/QmitkCtkPythonShell.cpp b/Modules/Python/QmitkCtkPythonShell.cpp
index f8c676dccb..c5f8a7aee0 100644
--- a/Modules/Python/QmitkCtkPythonShell.cpp
+++ b/Modules/Python/QmitkCtkPythonShell.cpp
@@ -1,91 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkCtkPythonShell.h"
#include
#include
#include
#include
#include
#include "mitkPythonService.h"
#include
#include
#include
struct QmitkCtkPythonShellData
{
mitk::PythonService* m_PythonService;
us::ServiceReference m_PythonServiceRef;
};
QmitkCtkPythonShell::QmitkCtkPythonShell(QWidget* parent)
: ctkPythonConsole(parent), d( new QmitkCtkPythonShellData )
{
MITK_DEBUG("QmitkCtkPythonShell") << "retrieving IPythonService";
us::ModuleContext* context = us::GetModuleContext();
d->m_PythonServiceRef = context->GetServiceReference();
d->m_PythonService = dynamic_cast ( context->GetService(d->m_PythonServiceRef) );
MITK_DEBUG("QmitkCtkPythonShell") << "checking IPythonService";
Q_ASSERT( d->m_PythonService );
MITK_DEBUG("QmitkCtkPythonShell") << "initialize m_PythonService";
this->initialize( d->m_PythonService->GetPythonManager() );
MITK_DEBUG("QmitkCtkPythonShell") << "m_PythonService initialized";
}
QmitkCtkPythonShell::~QmitkCtkPythonShell()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( d->m_PythonServiceRef );
delete d;
}
void QmitkCtkPythonShell::dragEnterEvent(QDragEnterEvent *event)
{
event->accept();
}
void QmitkCtkPythonShell::dropEvent(QDropEvent *event)
{
QList urls = event->mimeData()->urls();
for(int i = 0; i < urls.size(); i++)
{
d->m_PythonService->Execute( urls[i].toString().toStdString(), mitk::IPythonService::SINGLE_LINE_COMMAND );
}
}
bool QmitkCtkPythonShell::canInsertFromMimeData( const QMimeData *source ) const
{
return true;
}
void QmitkCtkPythonShell::executeCommand(const QString& command)
{
MITK_DEBUG("QmitkCtkPythonShell") << "executing command " << command.toStdString();
- ctkPythonConsole::executeCommand(command);
+ d->m_PythonService->Execute(command.toStdString(),mitk::IPythonService::MULTI_LINE_COMMAND);
d->m_PythonService->NotifyObserver(command.toStdString());
}
void QmitkCtkPythonShell::Paste(const QString &command)
{
if( this->isVisible() )
{
this->exec( command );
//this->executeCommand( command );
}
}
diff --git a/Modules/Python/QmitkPythonSnippets.cpp b/Modules/Python/QmitkPythonSnippets.cpp
index 975944557c..b0947c81af 100644
--- a/Modules/Python/QmitkPythonSnippets.cpp
+++ b/Modules/Python/QmitkPythonSnippets.cpp
@@ -1,483 +1,483 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonSnippets.h"
#include "QmitkPythonScriptEditorHighlighter.h"
#include
#include
#include
struct QmitkPythonSnippetsData
{
QString m_AutoSaveFileName;
QString m_SaveFileName;
QAction* m_PasteSnippet;
QAction* m_RemoveSnippet;
QAction* m_RenameSnippet;
QAction* m_AddSnippet;
QAction* m_RestoreDefaultSnippets;
QAction* m_LoadSnippets;
QAction* m_SaveSnippets;
QToolBar* m_Toolbar;
QComboBox* m_Name;
QTextEdit* m_Content;
QGridLayout* m_Layout;
QmitkPythonSnippets::QStringMap m_Snippets;
};
const QString QmitkPythonSnippets::DEFAULT_SNIPPET_FILE( ":/mitkPython/PythonSnippets.xml" );
const QString QmitkPythonSnippets::SNIPPETS_ROOT_XML_ELEMENT_NAME( "PythonSnippets" );
const QString QmitkPythonSnippets::SNIPPETS_XML_ELEMENT_NAME( "PythonSnippet" );
QmitkPythonSnippets::QmitkPythonSnippets( const QString& _AutoSaveFileName, QWidget* parent )
: QWidget(parent), d(new QmitkPythonSnippetsData)
{
d->m_SaveFileName = QDir::currentPath();
d->m_AutoSaveFileName = _AutoSaveFileName;
- if( !this->LoadStringMap( d->m_AutoSaveFileName, d->m_Snippets ) )
+ if( !QmitkPythonSnippets::LoadStringMap( d->m_AutoSaveFileName, d->m_Snippets ) )
{
- this->LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
+ QmitkPythonSnippets::LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
}
d->m_PasteSnippet = new QAction(this);
d->m_PasteSnippet->setObjectName(QString::fromUtf8("PasteSnippet"));
QIcon icon;
icon.addFile(QString::fromUtf8(":/mitkPython/edit-paste.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_PasteSnippet->setIcon(icon);
d->m_PasteSnippet->setToolTip("Paste snippet!");
d->m_PasteSnippet->setEnabled(false);
d->m_RemoveSnippet = new QAction(this);
d->m_RemoveSnippet->setObjectName(QString::fromUtf8("RemoveSnippet"));
QIcon icon1;
icon1.addFile(QString::fromUtf8(":/mitkPython/edit-delete.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RemoveSnippet->setIcon(icon1);
d->m_RemoveSnippet->setToolTip("Remove snippet.");
d->m_RemoveSnippet->setEnabled(false);
d->m_RenameSnippet = new QAction(this);
d->m_RenameSnippet->setObjectName(QString::fromUtf8("RenameSnippet"));
QIcon icon2;
icon2.addFile(QString::fromUtf8(":/mitkPython/edit-find-replace.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RenameSnippet->setIcon(icon2);
d->m_RenameSnippet->setToolTip("Rename snippet.");
d->m_RenameSnippet->setEnabled(false);
d->m_AddSnippet = new QAction(this);
d->m_AddSnippet->setObjectName(QString::fromUtf8("AddSnippet"));
QIcon icon3;
icon3.addFile(QString::fromUtf8(":/mitkPython/document-new.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_AddSnippet->setIcon(icon3);
d->m_AddSnippet->setToolTip("Add snippet.");
d->m_RestoreDefaultSnippets = new QAction(this);
d->m_RestoreDefaultSnippets->setObjectName(QString::fromUtf8("RestoreDefaultSnippets"));
QIcon icon4;
icon4.addFile(QString::fromUtf8(":/mitkPython/edit-clear.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_RestoreDefaultSnippets->setIcon(icon4);
d->m_RestoreDefaultSnippets->setToolTip("Restore default snippets");
d->m_LoadSnippets = new QAction(this);
d->m_LoadSnippets->setToolTip("Load Snippets from disk.");
d->m_LoadSnippets->setObjectName(QString::fromUtf8("LoadSnippets"));
QIcon icon5;
icon5.addFile(QString::fromUtf8(":/mitkPython/document-open.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_LoadSnippets->setIcon(icon5);
d->m_SaveSnippets = new QAction(this);
d->m_SaveSnippets->setToolTip("Save Snippets to disk.");
d->m_SaveSnippets->setObjectName(QString::fromUtf8("SaveSnippets"));
QIcon icon6;
icon6.addFile(QString::fromUtf8(":/mitkPython/document-save.png"), QSize(), QIcon::Normal, QIcon::Off);
d->m_SaveSnippets->setIcon(icon6);
d->m_SaveSnippets->setEnabled(false);
d->m_Toolbar = new QToolBar;
d->m_Toolbar->addAction( d->m_PasteSnippet );
d->m_Toolbar->addAction( d->m_AddSnippet );
d->m_Toolbar->addAction( d->m_RemoveSnippet );
d->m_Toolbar->addAction( d->m_RenameSnippet );
d->m_Toolbar->addAction( d->m_RestoreDefaultSnippets );
d->m_Toolbar->addAction( d->m_SaveSnippets );
d->m_Toolbar->addAction( d->m_LoadSnippets );
d->m_Name = new QComboBox;
d->m_Name->setObjectName(QString::fromUtf8("Name"));
d->m_Content = new QTextEdit(this);
d->m_Content->setObjectName(QString::fromUtf8("Content"));
d->m_Content->setEnabled(false);
QmitkPythonScriptEditorHighlighter* highlighter =
new QmitkPythonScriptEditorHighlighter( d->m_Content->document() );
d->m_Layout = new QGridLayout;
d->m_Layout->addWidget( d->m_Toolbar, 0, 0, 1, 1 );
d->m_Layout->addWidget( d->m_Name, 1, 0, 1, 1 );
d->m_Layout->addWidget( d->m_Content, 2, 0, 1, 1 );
d->m_Layout->setContentsMargins(2,2,2,2);
this->setLayout(d->m_Layout);
QMetaObject::connectSlotsByName(this);
this->Update();
}
QmitkPythonSnippets::~QmitkPythonSnippets()
{
delete d;
}
void QmitkPythonSnippets::on_PasteSnippet_triggered( bool )
{
emit PasteCommandRequested( d->m_Content->toPlainText() );
}
void QmitkPythonSnippets::on_RenameSnippet_triggered(bool)
{
QString oldname = d->m_Name->currentText();
QString name = oldname;
bool ok = false;
while( true )
{
name = QInputDialog::getText(this,
tr("Add new snippet"),
tr("Name of snippet:"),
QLineEdit::Normal,
name,
&ok);
if (ok)
{
if ( d->m_Snippets.contains(name) )
{
QMessageBox::warning(this,
tr("Duplicate name."),
tr("The entered name already exists. Enter another one or cancel the operation."),
QMessageBox::Ok,
QMessageBox::Ok );
}
else
{
QString tmpSnippet = d->m_Snippets[oldname];
d->m_Snippets.remove(oldname);
d->m_Snippets[name] = tmpSnippet;
this->Update(name);
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
break;
}
}
else
{
break;
}
}
}
void QmitkPythonSnippets::on_AddSnippet_triggered(bool)
{
bool ok;
QString name = QInputDialog::getText(this,
tr("Add new snippet"),
tr("Name of snippet:"),
QLineEdit::Normal,
"newSnippet",
&ok);
if (ok && !name.isEmpty())
{
MITK_DEBUG("QmitkPythonSnippets") << "creating unique name for " << name.toStdString();
name = this->CreateUniqueName(name);
MITK_DEBUG("QmitkPythonSnippets") << "creating snippet " << name.toStdString();
d->m_Snippets[name] = "";
this->Update(name);
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
QString QmitkPythonSnippets::CreateUniqueName( const QString& name ) const
{
QString newName = name;
size_t i = 2;
while( d->m_Snippets.contains(name) )
{
newName = name + QString("_%1").arg(i);
++i;
}
return newName;
}
void QmitkPythonSnippets::on_RemoveSnippet_triggered(bool)
{
QString name = d->m_Name->currentText();
QString question = QString("Really remove Snippet %1?").arg(name);
int remove = QMessageBox::question( this,
QString("Confirm removal"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( remove == QMessageBox::Yes || remove == QMessageBox::Ok )
{
d->m_Snippets.remove(name);
this->Update();
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_RestoreDefaultSnippets_triggered(bool)
{
QString question = QString("Really restore default Snippets?");
int remove = QMessageBox::question( this,
QString("Confirm restoring"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( remove == QMessageBox::Yes || remove == QMessageBox::Ok )
{
- this->LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
+ QmitkPythonSnippets::LoadStringMap( DEFAULT_SNIPPET_FILE, d->m_Snippets );
this->Update();
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_Name_currentIndexChanged(int i)
{
bool validSelection = i >= 0 ;
d->m_PasteSnippet->setEnabled(validSelection);
d->m_RemoveSnippet->setEnabled(validSelection);
d->m_RenameSnippet->setEnabled(validSelection);
d->m_Content->setEnabled(validSelection);
d->m_SaveSnippets->setEnabled(validSelection);
if( validSelection )
{
QString name = d->m_Name->currentText();
MITK_DEBUG("QmitkPythonSnippets") << "selected snippet " << name.toStdString();
d->m_Content->setText( d->m_Snippets[name] );
MITK_DEBUG("QmitkPythonSnippets") << "selected snippet content " << d->m_Snippets[name].toStdString();
}
}
void QmitkPythonSnippets::SaveStringMap(const QString &filename, const QmitkPythonSnippets::QStringMap &map) const
{
MITK_DEBUG("QmitkPythonSnippets") << "saving to xml file " << filename.toStdString();
if( filename.isEmpty() )
{
MITK_WARN("QmitkPythonSnippets") << "empty auto save file path given. quit.";
return;
}
QFile file(filename);
file.open(QIODevice::WriteOnly);
if( !file.isOpen() )
{
MITK_WARN("QmitkPythonSnippets") << "could not open file " << filename.toStdString() << " for writing";
return;
}
QXmlStreamWriter xmlWriter(&file);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement(SNIPPETS_ROOT_XML_ELEMENT_NAME);
QStringMap::const_iterator it = d->m_Snippets.begin();
while( it != d->m_Snippets.end() )
{
{
MITK_DEBUG("QmitkPythonSnippets") << "SNIPPETS_XML_ELEMENT_NAME " << SNIPPETS_XML_ELEMENT_NAME.toStdString();
MITK_DEBUG("QmitkPythonSnippets") << "writing item " << it.key().toStdString();
}
xmlWriter.writeStartElement(SNIPPETS_XML_ELEMENT_NAME);
xmlWriter.writeAttribute( "key", it.key() );
xmlWriter.writeAttribute( "value", it.value() );
xmlWriter.writeEndElement();
++it;
}
xmlWriter.writeEndDocument();
if( file.isOpen() )
file.close();
{
MITK_DEBUG("QmitkPythonSnippets") << "SaveStringMap successful ";
}
}
-bool QmitkPythonSnippets::LoadStringMap( const QString& filename, QmitkPythonSnippets::QStringMap& oldMap ) const
+bool QmitkPythonSnippets::LoadStringMap( const QString& filename, QmitkPythonSnippets::QStringMap& oldMap )
{
MITK_DEBUG("QmitkPythonSnippets") << "loading from xml file " << filename.toStdString();
QStringMap map;
QXmlStreamReader xmlReader;
QFile file;
QByteArray data;
// resource file
if( filename.startsWith(":") )
{
QResource res( filename );
data = QByteArray( reinterpret_cast< const char* >( res.data() ), res.size() );
xmlReader.addData( data );
}
else
{
file.setFileName( filename );
if (!file.open(QFile::ReadOnly | QFile::Text))
{
MITK_ERROR << "Error: Cannot read file " << qPrintable(filename)
<< ": " << qPrintable(file.errorString());
return false;
}
xmlReader.setDevice(&file);
}
xmlReader.readNext();
while(!xmlReader.atEnd())
{
xmlReader.readNext();
if(xmlReader.name() == SNIPPETS_XML_ELEMENT_NAME)
{
QXmlStreamAttributes attributes = xmlReader.attributes();
QString key;
QString value;
if(attributes.hasAttribute("key"))
{
key = attributes.value("key").toString();
}
if(attributes.hasAttribute("value"))
{
value = attributes.value("value").toString();
}
if( !key.isEmpty() )
{
MITK_DEBUG("QmitkPythonSnippets") << "loaded snippet " << key.toStdString();
MITK_DEBUG("QmitkPythonSnippets") << "value " << value.toStdString();
map[key] = value;
}
}
}
if (xmlReader.hasError())
{
MITK_ERROR << "Error: Failed to parse file "
<< qPrintable(filename) << ": "
<< qPrintable(xmlReader.errorString());
return false;
}
else if (file.error() != QFile::NoError)
{
MITK_ERROR << "Error: Cannot read file " << qPrintable(filename)
<< ": " << qPrintable(file.errorString());
return false;
}
if( file.isOpen() )
file.close();
oldMap = map;
return true;
}
void QmitkPythonSnippets::Update(const QString &name)
{
d->m_Name->clear();
d->m_Content->clear();
MITK_DEBUG("QmitkPythonSnippets") << "size of snippets " << d->m_Snippets.size();
QStringMap::const_iterator it = d->m_Snippets.begin();
while( it != d->m_Snippets.end() )
{
MITK_DEBUG("QmitkPythonSnippets") << "adding item " << it.key().toStdString();
d->m_Name->addItem( it.key() );
++it;
}
int index = d->m_Name->findText( name );
if( index >= 0 )
{
MITK_DEBUG("QmitkPythonSnippets") << "selecting index " << index;
d->m_Name->setCurrentIndex(index);
}
}
void QmitkPythonSnippets::on_Content_textChanged()
{
if( d->m_Content->isEnabled() )
{
QString name = d->m_Name->currentText();
QString snippet = d->m_Content->toPlainText();
d->m_Snippets[name] = snippet;
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
MITK_DEBUG("QmitkPythonSnippets") << "SaveStringMap successful";
}
}
void QmitkPythonSnippets::on_SaveSnippets_triggered(bool)
{
QString fileName = QFileDialog::getSaveFileName(this, "Save snippets", d->m_SaveFileName, "XML files (*.xml)");
if( !fileName.isEmpty() )
{
d->m_SaveFileName = fileName;
this->SaveStringMap( d->m_SaveFileName, d->m_Snippets );
}
}
void QmitkPythonSnippets::on_LoadSnippets_triggered(bool)
{
QString fileName = QFileDialog::getOpenFileName(this, "Load snippets", d->m_SaveFileName, "XML files (*.xml)");
if( !fileName.isEmpty() )
{
d->m_SaveFileName = fileName;
QString question = QString("Your current snippets will be overwritten. Proceed?");
int overwrite = QMessageBox::warning(this,
QString("Confirm overwrite"),
question,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No );
if( overwrite == QMessageBox::Yes )
{
this->LoadStringMap( d->m_SaveFileName, d->m_Snippets );
this->Update( d->m_Name->currentText() );
this->SaveStringMap( d->m_AutoSaveFileName, d->m_Snippets );
}
}
}
diff --git a/Modules/Python/QmitkPythonSnippets.h b/Modules/Python/QmitkPythonSnippets.h
index 39c808a419..998e0a635b 100644
--- a/Modules/Python/QmitkPythonSnippets.h
+++ b/Modules/Python/QmitkPythonSnippets.h
@@ -1,104 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _QmitkPythonSnippets_H
#define _QmitkPythonSnippets_H
#include
#include
#include
struct QmitkPythonSnippetsData;
///
/// a widget that holds snippets and serializes the snippets to a certain places
class MITK_PYTHON_EXPORT QmitkPythonSnippets: public QWidget
{
Q_OBJECT
public:
static const QString DEFAULT_SNIPPET_FILE;
static const QString SNIPPETS_ROOT_XML_ELEMENT_NAME;
static const QString SNIPPETS_XML_ELEMENT_NAME;
///
/// typedef for string map
typedef QMap QStringMap;
///
/// build ui here
/// the snippets will be loaded from _AutoSaveFileName if not empty and readable
/// otherwise the default snippets will be loaded
QmitkPythonSnippets( const QString& _AutoSaveFileName="", QWidget* parent=0 );
///
/// delete d pointer
virtual ~QmitkPythonSnippets();
+ ///
+ /// read string map from xml file
+ static bool LoadStringMap( const QString& filename, QStringMap& oldMap );
+
signals:
///
/// this class whishes to paste sth command
void PasteCommandRequested(const QString& command);
protected slots:
///
/// emits PasteCommandRequested signal
void on_PasteSnippet_triggered( bool checked = false );
///
/// ask for name as long as it exists, call update()
void on_RenameSnippet_triggered( bool checked = false );
///
/// ask for name, create snippet, call update()
void on_AddSnippet_triggered( bool checked = false );
///
/// remove the current snippet, call update()
void on_RemoveSnippet_triggered( bool checked = false );
///
/// call LoadStringMap with d->m_DefaultSnippetsAutoSaveFileName
void on_RestoreDefaultSnippets_triggered( bool checked = false );
///
/// update action state (enable/disable), update text box
void on_Name_currentIndexChanged( int i );
///
/// save changed snippet
void on_Content_textChanged();
///
/// ask for file, save snippets
void on_SaveSnippets_triggered( bool checked = false );
///
/// ask for file, load snippets (do not replace)
void on_LoadSnippets_triggered( bool checked = false );
protected:
///
/// write string map to xml file
void SaveStringMap( const QString& filename, const QStringMap& map ) const;
///
- /// read string map from xml file
- bool LoadStringMap( const QString& filename, QStringMap& oldMap ) const;
- ///
/// creates a name which does not exist in the list
QString CreateUniqueName(const QString &name) const;
///
/// update combo box
/// if name is passed, the according element will be selected
void Update(const QString &name = "");
private:
///
/// d pointer declaration (holds members)
QmitkPythonSnippetsData* d;
};
#endif // _QmitkPythonSnippets_H_INCLUDED
diff --git a/Modules/Python/QmitkPythonVariableStackTableModel.cpp b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
index a06b9f9002..d345dd0962 100755
--- a/Modules/Python/QmitkPythonVariableStackTableModel.cpp
+++ b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
@@ -1,223 +1,230 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonVariableStackTableModel.h"
#include
#include
#include
#include
#include
#include
const QString QmitkPythonVariableStackTableModel::MITK_IMAGE_VAR_NAME = "mitkImage";
const QString QmitkPythonVariableStackTableModel::MITK_SURFACE_VAR_NAME = "mitkSurface";
QmitkPythonVariableStackTableModel::QmitkPythonVariableStackTableModel(QObject *parent)
:QAbstractTableModel(parent)
{
us::ModuleContext* context = us::GetModuleContext();
m_PythonServiceRef = context->GetServiceReference();
m_PythonService = context->GetService(m_PythonServiceRef);
m_PythonService->AddPythonCommandObserver( this );
}
QmitkPythonVariableStackTableModel::~QmitkPythonVariableStackTableModel()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( m_PythonServiceRef );
m_PythonService->RemovePythonCommandObserver( this );
}
bool QmitkPythonVariableStackTableModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
// Early exit, returning true, but not actually doing anything (ignoring data).
if (action == Qt::IgnoreAction)
return true;
// Note, we are returning true if we handled it, and false otherwise
bool returnValue = false;
if(data->hasFormat("application/x-mitk-datanodes"))
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "dropped MITK DataNode";
returnValue = true;
QString arg = QString(data->data("application/x-mitk-datanodes").data());
QStringList listOfDataNodeAddressPointers = arg.split(",");
QStringList::iterator slIter;
int i = 0;
- int j = 0;
for (slIter = listOfDataNodeAddressPointers.begin();
slIter != listOfDataNodeAddressPointers.end();
slIter++)
{
long val = (*slIter).toLong();
mitk::DataNode* node = static_cast((void*)val);
mitk::Image* mitkImage = dynamic_cast(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "mitkImage is not null " << (mitkImage != 0? "true": "false");
+ QRegExp rx("^\\d");
+ QString varName(node->GetName().c_str());
+ // regex replace every character that is not allowed in a python variable
+ varName = varName.replace(QRegExp("[.\\+\\-*\\s\\/\\n\\t\\r]"),QString("_"));
+
if( mitkImage )
{
- QString varName = MITK_IMAGE_VAR_NAME;
+ if ( varName.isEmpty() )
+ varName = MITK_IMAGE_VAR_NAME;
+ if ( rx.indexIn(varName) == 0)
+ varName.prepend("_").prepend(MITK_IMAGE_VAR_NAME);
+
if( i > 0 )
- varName = QString("%1%2").arg(MITK_IMAGE_VAR_NAME).arg(i);
+ varName = QString("%1%2").arg(varName).arg(i);
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
bool exportAsCvImage = mitkImage->GetDimension() == 2 && m_PythonService->IsOpenCvPythonWrappingAvailable();
if( exportAsCvImage )
{
int ret = QMessageBox::question(NULL, "Export option",
- "2D image detected. Export as OpenCV image to Python instead of an ITK image?",
+ "2D image detected. Export as OpenCV image to Python instead of an SimpleITK image?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
-
exportAsCvImage = ret == QMessageBox::Yes;
if(exportAsCvImage)
{
- m_PythonService->CopyToPythonAsCvImage( mitkImage, MITK_IMAGE_VAR_NAME.toStdString() );
+ varName = MITK_IMAGE_VAR_NAME;
+ m_PythonService->CopyToPythonAsCvImage( mitkImage, varName.toStdString() );
++i;
}
}
if( !exportAsCvImage )
{
- if( m_PythonService->IsItkPythonWrappingAvailable() )
+ if( m_PythonService->IsSimpleItkPythonWrappingAvailable() )
{
- m_PythonService->CopyToPythonAsItkImage( mitkImage, MITK_IMAGE_VAR_NAME.toStdString() );
+ m_PythonService->CopyToPythonAsSimpleItkImage( mitkImage, varName.toStdString() );
++i;
}
else
{
- MITK_ERROR << "ITK Python wrapping not available. Skipping export for image " << node->GetName();
+ MITK_ERROR << "SimpleITK Python wrapping not available. Skipping export for image " << node->GetName();
}
}
}
else
{
mitk::Surface* surface = dynamic_cast(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "found surface";
if( surface )
{
- QString varName = MITK_SURFACE_VAR_NAME;
- MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
+ if (varName.isEmpty() )
+ varName = MITK_SURFACE_VAR_NAME;
+ if ( rx.indexIn(varName) == 0)
+ varName.prepend("_").prepend(MITK_SURFACE_VAR_NAME);
- if( j > 0 )
- varName = QString("%1%2").arg(MITK_SURFACE_VAR_NAME).arg(j);
- MITK_DEBUG("varName") << "varName" << varName.toStdString();
+ MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName;
if( m_PythonService->IsVtkPythonWrappingAvailable() )
{
- m_PythonService->CopyToPythonAsVtkPolyData( surface, MITK_SURFACE_VAR_NAME.toStdString() );
- ++j;
+ m_PythonService->CopyToPythonAsVtkPolyData( surface, varName.toStdString() );
}
else
{
MITK_ERROR << "VTK Python wrapping not available. Skipping export for surface " << node->GetName();
}
}
}
}
}
return returnValue;
}
QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
QVariant headerData;
// show only horizontal header
if ( role == Qt::DisplayRole )
{
if( orientation == Qt::Horizontal )
{
// first column: "Attribute"
if(section == 0)
headerData = "Attribute";
else if(section == 1)
headerData = "Type";
else if(section == 2)
headerData = "Value";
}
}
return headerData;
}
Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if(index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags;
else
return Qt::ItemIsDropEnabled | flags;
}
int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const
{
return m_VariableStack.size();
}
int QmitkPythonVariableStackTableModel::columnCount(const QModelIndex &) const
{
return 3;
}
QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && !m_VariableStack.empty())
{
if(role == Qt::DisplayRole)
{
mitk::PythonVariable item = m_VariableStack.at(index.row());
if(index.column() == 0)
return QString::fromStdString(item.m_Name);
if(index.column() == 1)
return QString::fromStdString(item.m_Type);
if(index.column() == 2)
return QString::fromStdString(item.m_Value);
}
}
return QVariant();
}
QStringList QmitkPythonVariableStackTableModel::mimeTypes() const
{
return QAbstractTableModel::mimeTypes();
QStringList types;
types << "application/x-mitk-datanodes";
types << "application/x-qabstractitemmodeldatalist";
return types;
}
Qt::DropActions QmitkPythonVariableStackTableModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
void QmitkPythonVariableStackTableModel::CommandExecuted(const std::string& pythonCommand)
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "command was executed " << pythonCommand;
m_VariableStack = m_PythonService->GetVariableStack();
QAbstractTableModel::reset();
}
std::vector QmitkPythonVariableStackTableModel::GetVariableStack() const
{
return m_VariableStack;
}
diff --git a/Modules/Python/QmitkPythonVariableStackTableView.cpp b/Modules/Python/QmitkPythonVariableStackTableView.cpp
index 4921eaec4f..a5a7425567 100755
--- a/Modules/Python/QmitkPythonVariableStackTableView.cpp
+++ b/Modules/Python/QmitkPythonVariableStackTableView.cpp
@@ -1,107 +1,116 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonVariableStackTableView.h"
#include
#include
#include
#include
#include
+#include
QmitkPythonVariableStackTableView::QmitkPythonVariableStackTableView(QWidget *parent)
:QTableView(parent)
{
m_TableModel = new QmitkPythonVariableStackTableModel(parent);
m_TableModel->CommandExecuted("");
this->setSelectionBehavior( QAbstractItemView::SelectRows );
this->setAlternatingRowColors(true);
this->setDropIndicatorShown(true);
this->setAcceptDrops(true);
this->setModel( m_TableModel );
us::ModuleContext* context = us::GetModuleContext();
us::ServiceReference serviceRef = context->GetServiceReference();
m_PythonService = context->GetService(serviceRef);
connect( this, SIGNAL(doubleClicked ( const QModelIndex& )), this, SLOT( OnVariableStackDoubleClicked(const QModelIndex&) ) );
}
QmitkPythonVariableStackTableView::~QmitkPythonVariableStackTableView()
{
}
void QmitkPythonVariableStackTableView::SetDataStorage(mitk::DataStorage *_DataStorage)
{
m_DataStorage = _DataStorage;
}
void QmitkPythonVariableStackTableView::OnVariableStackDoubleClicked(const QModelIndex &index)
{
if( m_DataStorage.IsNull() || m_PythonService == 0 )
{
MITK_ERROR << "QmitkPythonVariableStackTableView not configured correctly. Quit";
return;
}
int row = index.row();
std::vector variableStack = m_TableModel->GetVariableStack();
{
MITK_DEBUG("QmitkPythonVariableStackTableView") << "row " << row;
MITK_DEBUG("QmitkPythonVariableStackTableView") << "variableStack.size(): " << variableStack.size();
}
QString varName = QString::fromStdString( variableStack.at(row).m_Name );
QString type = QString::fromStdString( variableStack.at(row).m_Type );
QString value = QString::fromStdString( variableStack.at(row).m_Value );
{
MITK_DEBUG("QmitkPythonVariableStackTableView") << "varName: " << varName.toStdString();
MITK_DEBUG("QmitkPythonVariableStackTableView") << "type: " << type.toStdString();
}
mitk::Image::Pointer mitkImage;
mitk::Surface::Pointer mitkSurface;
- if( type.startsWith("itkImage") )
+ if( type.startsWith("Image") )
{
- mitkImage = m_PythonService->CopyItkImageFromPython(varName.toStdString());
+ mitkImage = m_PythonService->CopySimpleItkImageFromPython(varName.toStdString());
}
else if( type.startsWith("numpy.ndarray") )
{
mitkImage = m_PythonService->CopyCvImageFromPython(varName.toStdString());
}
else if( value.startsWith("(vtkPolyData)") )
{
mitkSurface = m_PythonService->CopyVtkPolyDataFromPython(varName.toStdString());
}
std::string nodeName = varName.toStdString();
- mitk::DataNode::Pointer node = mitk::DataNode::New();
- node->SetName ( nodeName );
+ mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode(nodeName);
+
+ // only create data node if it does not exist
+ if ( node.IsNull() )
+ {
+ node = mitk::DataNode::New();
+ node->SetName ( nodeName );
+ m_DataStorage->Add(node);
+ }
if( mitkImage.IsNotNull() )
{
node->SetData( mitkImage );
}
else if( mitkSurface.IsNotNull() )
{
node->SetData( mitkSurface );
+ // init renderwindow geometry
+ mitk::RenderingManager::GetInstance()->InitializeViews(mitkSurface->GetGeometry());
}
- m_DataStorage->Add(node);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
diff --git a/Modules/Python/Testing/CMakeLists.txt b/Modules/Python/Testing/CMakeLists.txt
index c1470c885b..153cd81e2e 100644
--- a/Modules/Python/Testing/CMakeLists.txt
+++ b/Modules/Python/Testing/CMakeLists.txt
@@ -1,4 +1 @@
MITK_CREATE_MODULE_TESTS()
-
-mitkAddCustomModuleTest(mitkCopyToPythonAsItkImage_CopyPic3DToPythonAndBackToMitk_ImageIsEqual mitkCopyToPythonAsItkImageTest ${MITK_DATA_DIR}/Pic3D.nrrd)
-
diff --git a/Modules/Python/Testing/files.cmake b/Modules/Python/Testing/files.cmake
index c8e9fe00e2..fb6dc38d7e 100644
--- a/Modules/Python/Testing/files.cmake
+++ b/Modules/Python/Testing/files.cmake
@@ -1,7 +1,13 @@
set(MODULE_TESTS
mitkPythonTest.cpp
+ mitkVtkPythonTest.cpp
)
-set(MODULE_CUSTOM_TESTS
- mitkCopyToPythonAsItkImageTest.cpp
-)
+if(MITK_USE_OpenCV)
+ set(MODULE_TESTS ${MODULE_TESTS} mitkCvPythonTest.cpp)
+endif()
+
+if(MITK_USE_SimpleITK)
+ set(MODULE_TESTS ${MODULE_TESTS} mitkSimpleItkPythonTest.cpp)
+endif()
+
diff --git a/Modules/Python/Testing/mitkCommonPythonTest.h b/Modules/Python/Testing/mitkCommonPythonTest.h
new file mode 100644
index 0000000000..420e97bcb7
--- /dev/null
+++ b/Modules/Python/Testing/mitkCommonPythonTest.h
@@ -0,0 +1,72 @@
+
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace mitk
+{
+
+class CommonPythonTestSuite : public mitk::TestFixture
+{
+
+protected:
+ mitk::PythonService* m_PythonService;
+ mitk::Image::Pointer m_Image;
+ mitk::Image::Pointer m_Image2D;
+ mitk::Surface::Pointer m_Surface;
+ QMap m_Snippets;
+
+public:
+
+ void setUp()
+ {
+ //get the context of the python module
+ us::Module* module = us::ModuleRegistry::GetModule("MitkPython");
+ us::ModuleContext* context = module->GetModuleContext();
+ //get the service which is generated in the PythonModuleActivator
+ us::ServiceReference serviceRef = context->GetServiceReference();
+ m_PythonService = dynamic_cast( context->GetService(serviceRef) );
+
+ m_Image = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd"));
+ m_Image2D = mitk::IOUtil::LoadImage(GetTestDataFilePath("Png2D-bw.png"));
+ m_Surface = mitk::IOUtil::LoadSurface(GetTestDataFilePath("binary.stl"));
+
+ QmitkPythonSnippets::LoadStringMap(QmitkPythonSnippets::DEFAULT_SNIPPET_FILE,m_Snippets);
+ }
+
+ void tearDown()
+ {
+ m_Image = NULL;
+ m_Image2D = NULL;
+ m_Surface = NULL;
+ }
+};
+
+}
diff --git a/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp b/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp
deleted file mode 100644
index c9d0e5cd32..0000000000
--- a/Modules/Python/Testing/mitkCopyToPythonAsItkImageTest.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*===================================================================
-
-The Medical Imaging Interaction Toolkit (MITK)
-
-Copyright (c) German Cancer Research Center,
-Division of Medical and Biological Informatics.
-All rights reserved.
-
-This software is distributed WITHOUT ANY WARRANTY; without
-even the implied warranty of MERCHANTABILITY or FITNESS FOR
-A PARTICULAR PURPOSE.
-
-See LICENSE.txt or http://www.mitk.org for details.
-
-===================================================================*/
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-int mitkCopyToPythonAsItkImageTest(int /*argc*/, char* argv[])
-{
- MITK_TEST_BEGIN("mitkCopyToPythonAsItkImageTest")
-
- //get the context of the python module
- us::Module* module = us::ModuleRegistry::GetModule("MitkPython");
- us::ModuleContext* context = module->GetModuleContext();
- //get the service which is generated in the PythonModuleActivator
- us::ServiceReference serviceRef = context->GetServiceReference();
- mitk::PythonService* pythonService = dynamic_cast( context->GetService(serviceRef) );
- MITK_TEST_CONDITION(pythonService->IsItkPythonWrappingAvailable() == true, "Is Python available?");
-
- mitk::Image::Pointer testImage = mitk::IOUtil::LoadImage(std::string(argv[1]));
-
- //give it a name in python
- std::string nameOfImageInPython("mitkImage");
-
- MITK_TEST_CONDITION( pythonService->CopyToPythonAsItkImage( testImage, nameOfImageInPython) == true, "Valid image copied to python import should return true.");
- mitk::Image::Pointer pythonImage = pythonService->CopyItkImageFromPython(nameOfImageInPython);
-
-
- itk::Index<3> index;
- index[0] = 128;
- index[1] = 128;
- index[2] = 24;
-
- try{
- // pic3D of type char
- mitk::ImagePixelReadAccessor pythonImageAccesor(pythonImage);
-
- //TODO Use the assert comparison methods once we have them implemented and remove GetPixelValueByIndex
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(0) == 256, "Is the 1st dimension of Pic3D still 256?");
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(1) == 256, "Is the 2nd dimension of Pic3D still 256?");
- MITK_TEST_CONDITION( pythonImageAccesor.GetDimension(2) == 49, "Is the 3rd dimension of Pic3D still 49?");
-
- MITK_TEST_CONDITION( pythonImageAccesor.GetPixelByIndex(index) == 96, "Is the value of Pic3D at (128,128,24) still 96?");
- }catch(...)
- {
- MITK_TEST_CONDITION( false, "Image is not readable! ");
- }
-
- MITK_TEST_END()
-}
diff --git a/Modules/Python/Testing/mitkCvPythonTest.cpp b/Modules/Python/Testing/mitkCvPythonTest.cpp
new file mode 100644
index 0000000000..6f41448807
--- /dev/null
+++ b/Modules/Python/Testing/mitkCvPythonTest.cpp
@@ -0,0 +1,58 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include
+
+class mitkCvPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkCvPythonTestSuite);
+ MITK_TEST(testCVImageTransfer);
+ MITK_TEST(testOpenCVMedianFilter);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void testCVImageTransfer()
+ {
+ std::string varName("mitkImage");
+ CPPUNIT_ASSERT_MESSAGE ( "Is OpenCV Python Wrapping available?",
+ m_PythonService->IsOpenCvPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.",
+ m_PythonService->CopyToPythonAsCvImage( m_Image2D, varName) == true );
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopyCvImageFromPython(varName);
+
+ // todo pixeltypes do not match, cv is changing it
+ //CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal after transfer.",
+ // mitk::Equal(pythonImage,m_Image2D) );
+ }
+
+ //TODO opencv median filter, add cpp test code
+ void testOpenCVMedianFilter()
+ {
+ // simple itk median filter in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is OpenCV Python Wrapping available?", m_PythonService->IsOpenCvPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.", m_PythonService->CopyToPythonAsCvImage(m_Image2D, "mitkImage") == true );
+
+ m_PythonService->Execute( m_Snippets["opencv median filter"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkCvPython)
diff --git a/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp b/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp
new file mode 100644
index 0000000000..e2d6cce2cb
--- /dev/null
+++ b/Modules/Python/Testing/mitkSimpleItkPythonTest.cpp
@@ -0,0 +1,201 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+#include
+#include
+#include
+
+#include "SimpleITK.h"
+
+namespace sitk = itk::simple;
+
+namespace mitk {
+ static mitk::Image::Pointer SimpleItkToMitkImage( sitk::Image& sitkImage );
+ static sitk::Image MitkToSimpleItkImage( mitk::Image* image );
+}
+
+sitk::Image mitk::MitkToSimpleItkImage( mitk::Image* image )
+{
+ const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
+ mitk::Point3D origin = image->GetGeometry()->GetOrigin();
+ mitk::PixelType pixelType = image->GetPixelType();
+ mitk::ImageReadAccessor ra(image);
+ void* buffer = (void*) ra.GetData();
+ sitk::ImportImageFilter importer;
+
+ std::vector sitkSpacing;
+ sitkSpacing.push_back(spacing[0]);
+ sitkSpacing.push_back(spacing[1]);
+ sitkSpacing.push_back(spacing[2]);
+ std::vector sitkOrigin;
+ sitkOrigin.push_back(origin[0]);
+ sitkOrigin.push_back(origin[1]);
+ sitkOrigin.push_back(origin[2]);
+ std::vector sitkSize;
+
+ for ( unsigned int i = 0; i < image->GetDimension(); ++i )
+ sitkSize.push_back(image->GetDimensions()[i]);
+
+ importer.SetSpacing(sitkSpacing);
+ importer.SetSize(sitkSize);
+ importer.SetOrigin(sitkOrigin);
+
+ if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
+ importer.SetBufferAsDouble((double*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
+ importer.SetBufferAsFloat((float*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
+ importer.SetBufferAsInt16((int16_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
+ importer.SetBufferAsInt8((int8_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
+ importer.SetBufferAsInt32((int32_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
+ importer.SetBufferAsInt64((int64_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
+ importer.SetBufferAsUInt8((uint8_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
+ importer.SetBufferAsUInt32((uint32_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
+ importer.SetBufferAsUInt64((uint64_t*) buffer);
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
+ importer.SetBufferAsUInt16((uint16_t*) buffer);
+ }
+
+ return importer.Execute();
+}
+
+mitk::Image::Pointer mitk::SimpleItkToMitkImage( sitk::Image& sitkImage )
+{
+ mitk::Image::Pointer image = mitk::Image::New();
+ void* buffer = NULL;
+ mitk::PixelType pixelType = MakeScalarPixelType();
+ std::vector sitkSpacing = sitkImage.GetSpacing();
+ double spacing[3] = { sitkSpacing[0], sitkSpacing[1], sitkSpacing[2] };
+ std::vector sitkOrigin = sitkImage.GetOrigin();
+ double origin[3] = { sitkOrigin[0], sitkOrigin[1], sitkOrigin[2] };
+ std::vector sitkSize = sitkImage.GetSize();
+ unsigned int dimensions[4] = { 1,1,1,1};
+
+ for ( size_t i = 0; i < sitkSize.size(); ++i )
+ dimensions[i] = sitkSize[i];
+
+ size_t size = 0;
+ if ( sitkImage.GetPixelIDValue() == sitk::sitkInt8 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsInt8();
+ size = sizeof(char);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt16 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsInt16();
+ size = sizeof(short);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt32 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsInt32();
+ size = sizeof(int);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkInt64 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsInt64();
+ size = sizeof(long);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt8 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsUInt8();
+ size = sizeof(unsigned char);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt16 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsUInt16();
+ size = sizeof(unsigned short);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt32 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsUInt32();
+ size = sizeof(unsigned int);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkUInt64 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsUInt64();
+ size = sizeof(unsigned long);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkFloat32 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsFloat();
+ size = sizeof(float);
+ } else if( sitkImage.GetPixelIDValue() == sitk::sitkFloat64 ) {
+ pixelType = MakeScalarPixelType();
+ buffer = (void*) sitkImage.GetBufferAsDouble();
+ size = sizeof(double);
+ }
+
+ image->Initialize(pixelType,sitkImage.GetDimension(),dimensions);
+ image->SetSpacing(spacing);
+ image->SetOrigin(origin);
+
+ for(size_t i = 0; i < sitkSize.size(); ++i )
+ size *= sitkSize[i];
+
+ mitk::ImageWriteAccessor wa(image);
+
+ memcpy(wa.GetData(),buffer, size);
+
+ return image;
+}
+
+
+class mitkSimpleItkPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkSimpleItkPythonTestSuite);
+ MITK_TEST(testSimpleItkImageTransfer);
+ MITK_TEST(testSimpleITKMedianFilterSnippet);
+ CPPUNIT_TEST_SUITE_END();
+
+
+public:
+
+ void testSimpleItkImageTransfer()
+ {
+ std::string varName("mitkImage");
+ CPPUNIT_ASSERT_MESSAGE ( "Is SimpleITK Python Wrapping available?",
+ m_PythonService->IsSimpleItkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.",
+ m_PythonService->CopyToPythonAsSimpleItkImage( m_Image, varName) == true );
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopySimpleItkImageFromPython(varName);
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal after transfer.",
+ mitk::Equal(*pythonImage.GetPointer(),*m_Image.GetPointer(), mitk::eps,true) );
+ }
+
+
+ void testSimpleITKMedianFilterSnippet()
+ {
+ // simple itk median filter in cpp
+ sitk::MedianImageFilter medianFilter;
+ medianFilter.SetRadius(1);
+ sitk::Image sitkImage = medianFilter.Execute(mitk::MitkToSimpleItkImage(m_Image));
+ mitk::Image::Pointer mitkImage = mitk::SimpleItkToMitkImage(sitkImage);
+
+ // simple itk median filter in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is SimpleItk Python Wrapping available?", m_PythonService->IsSimpleItkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid image copied to python import should return true.", m_PythonService->CopyToPythonAsSimpleItkImage(m_Image, "mitkImage") == true );
+
+ m_PythonService->Execute( m_Snippets["medianfilter"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Image::Pointer pythonImage = m_PythonService->CopySimpleItkImageFromPython("mitkImage_new");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if images are equal.", mitk::Equal(*pythonImage.GetPointer(), *mitkImage.GetPointer(),mitk::eps,true) );
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkSimpleItkPython)
diff --git a/Modules/Python/Testing/mitkVtkPythonTest.cpp b/Modules/Python/Testing/mitkVtkPythonTest.cpp
new file mode 100644
index 0000000000..3fb2662006
--- /dev/null
+++ b/Modules/Python/Testing/mitkVtkPythonTest.cpp
@@ -0,0 +1,95 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include
+#include
+// vtk cone sample snippet
+#include
+// vtk decimate pro snippet
+#include
+
+#include
+
+class mitkVtkPythonTestSuite : public mitk::CommonPythonTestSuite
+{
+ CPPUNIT_TEST_SUITE(mitkVtkPythonTestSuite);
+ MITK_TEST(testSurfaceTransfer);
+ MITK_TEST(testVtkCreateConePythonSnippet);
+ MITK_TEST(testVtkDecimateProPythonSnippet);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void testSurfaceTransfer()
+ {
+ std::string varName("mitkSurface");
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid surface copied to python import should return true.",
+ m_PythonService->CopyToPythonAsVtkPolyData( m_Surface, varName) == true );
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython(varName);
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if surfaces are equal after transfer.", mitk::Equal(*pythonSurface.GetPointer(),*m_Surface.GetPointer(),mitk::eps,true) );
+ }
+
+ void testVtkCreateConePythonSnippet()
+ {
+ // cone in cpp
+ mitk::Surface::Pointer mitkSurface = mitk::Surface::New();
+ vtkSmartPointer coneSrc = vtkSmartPointer::New();
+ coneSrc->SetResolution(60);
+ coneSrc->SetCenter(-2,0,0);
+ coneSrc->Update();
+ mitkSurface->SetVtkPolyData(coneSrc->GetOutput());
+
+ // run python code
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ m_PythonService->Execute( m_Snippets["vtk: create cone"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython("cone");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if cones are equal.", mitk::Equal(*pythonSurface.GetPointer(), *mitkSurface.GetPointer(), mitk::eps,true) );
+ }
+
+ void testVtkDecimateProPythonSnippet()
+ {
+ // decimate pro in cpp
+ mitk::Surface::Pointer mitkSurface = mitk::Surface::New();
+ vtkSmartPointer deci = vtkSmartPointer::New();
+ deci->SetInputData(m_Surface->GetVtkPolyData());
+ deci->SetTargetReduction(0.9);
+ deci->PreserveTopologyOn();
+ deci->Update();
+ mitkSurface->SetVtkPolyData(deci->GetOutput());
+
+ // decimate pro in python
+ CPPUNIT_ASSERT_MESSAGE ( "Is VTK Python Wrapping available?", m_PythonService->IsVtkPythonWrappingAvailable() == true );
+
+ CPPUNIT_ASSERT_MESSAGE( "Valid surface copied to python import should return true.", m_PythonService->CopyToPythonAsVtkPolyData( m_Surface, "mitkSurface") == true );
+
+ m_PythonService->Execute( m_Snippets["vtk.vtkDecimatePro"].toStdString(), mitk::IPythonService::MULTI_LINE_COMMAND );
+ CPPUNIT_ASSERT_MESSAGE( "Python execute error occured.", !m_PythonService->PythonErrorOccured());
+
+ mitk::Surface::Pointer pythonSurface = m_PythonService->CopyVtkPolyDataFromPython("mitkSurface_new");
+
+ CPPUNIT_ASSERT_MESSAGE( "Compare if surfaces are equal.", mitk::Equal(*pythonSurface.GetPointer(), *mitkSurface.GetPointer(), mitk::eps,true) );
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkVtkPython)
diff --git a/Modules/Python/documentation/mitkPython.dox b/Modules/Python/documentation/mitkPython.dox
index dbfb3994e9..52f27b2c52 100644
--- a/Modules/Python/documentation/mitkPython.dox
+++ b/Modules/Python/documentation/mitkPython.dox
@@ -1,43 +1,49 @@
/**
\page mitkPython_Overview The MITK Python Module
-Brief description
-The MITK Python Module provides a service class for interactively run python code (passed as C++ strings) and evaluate the results. Furthermore the service class offers means to convert an MITK Image to an ITK/OpenCV image in their wrapped python environment. Thus, one can process MITK images with Python Code from the OpenCV and ITK wrapping system. Furthermore one can convert an mitk::Surface to a vtkPolyData in its Python environment.
-Under the hood, the MITK build system takes care that the wrapping build process for ITK/VTK/OpenCV is correctly initiated and all paths are correctly set within MITK code.
-
-Build Instructions
-- Install Python 2.x
-- Activate MITK_USE_Python in the superbuild process of MITK
-- Provide CMake with the correct Python paths (if not found automatically)
-- Build MITK: All wrapping will be setup by the MITK superbuild routine
-
-Known problems and workarounds
-
-System: Linux/OSX/gcc
-Problem: An error during the build process occurs:
-
-Linking CXX shared library libPythonQt.so
-/usr/bin/ld: error: /usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../../lib/libpython2.7.a(abstract.o): requires dynamic R_X86_64_PC32 reloc against 'PyErr_Occurred' which may overflow at runtime; recompile with -fPIC
-
-Workaround: Try setting the CMake var PYTHON_LIBRARY to the shared object, e.g. /usr/lib/libpython2.7.so
-
-System: Linux/gcc (maybe Mac OS)
-Problem: An error during the build process occurs:
-
-Scanning dependencies of target install_wrapitk_compatibility
-[ 40%] Built target install_wrapitk_compatibility
-[ 40%] Generating swigrun.xml
-gccxml_cc1plus: error: gccxml_builtins.h: No such file or directory
-make[5]: *** [Wrapping/WrapITK/SwigRuntime/swigrun.xml] Error 1
-make[4]: *** [Wrapping/WrapITK/SwigRuntime/CMakeFiles/SwigRuntimePython.dir/all] Error 2
-make[3]: *** [all] Error 2
-make[2]: *** [ITK-cmake/src/ITK-stamp/ITK-build] Error 2
-make[1]: *** [CMakeFiles/ITK.dir/all] Error 2
-make: *** [all] Error 2
-
-Workaround: Install CableSwig from the software repo and set the CMake var EXTERNAL_CableSwig_DIR to the directory containing CableSwigConfig.cmake, on linux usually /usr/lib/CableSwig
-
+\section sec1 Brief description
+The MITK Python Module provides a service class for interactively run python code (passed as C++ strings) and
+evaluate the results. Furthermore the service class offers means to convert an MITK Image to an ITK/OpenCV image in their wrapped python environment.
+Thus, one can process MITK images with Python Code from the OpenCV and ITK wrapping system.
+Furthermore one can convert an mitk::Surface to a vtkPolyData in its Python environment.
+Under the hood, the MITK build system takes care that the wrapping build process for SimpleITK/VTK/OpenCV is correctly initiated and all paths are correctly set within MITK code.
+To use the features of the different toolkits make sure they are enabled during the superbuild process.
+\section sec2 Build Instructions
+
+The following build options are available:
+
+ - MITK_USE_Python
+
- MITK_USE_SYSTEM_PYTHON
+
+
+\subsection ssec1 MITK_USE_Python
+MITK_USE_Python enables the python wrapping in MITK. When the option is activated
+the build of the additional dependency SimpleITK is also enabled. The default behaviour is to download and build
+Python 2.7.3 with numpy and embed it into MITK.To use an own custom runtime see MITK_USE_SYSTEM_PYTHON.
+
+\subsection ssec2 MITK_USE_SYSTEM_PYTHON
+This option is deactivated by default. If MITK_USE_SYSTEM_PYTHON is activated the python runtime from the system is used.
+The user can also specify it's own runtime by modifing the variables added by the
+FindPythonLib.cmake script. Note: A Python runtime with numpy is needed to use the MITK Python wrapping.
+
+\section sec3 Suported Data Types
+The following data types in MITK are supported in the MITK Python Wrapping:
+
+
+\subsection ssec4 Image
+Mitk Images can be transferred to python. The images are copied in-memory and
+transferred as a numpy array to Python and vice versa. The MITK python wrapping creates a SimpleITK image
+using the numpy array with the properties of the MITK Image. Two dimensional images
+can also be transferred as an OpenCV image to python.
+
+\subsection ssec5 Surface
+Surfaces within mitk can be transferred as a vtkPolyData Object to Python.
+The surfaces are fully memory mapped. When changing a python wrapped surface
+the original object is also modified on the C++ side of MITK.
*/
diff --git a/Modules/Python/files.cmake b/Modules/Python/files.cmake
index 66fb3a3ce7..c4fe74b329 100644
--- a/Modules/Python/files.cmake
+++ b/Modules/Python/files.cmake
@@ -1,28 +1,34 @@
SET(CPP_FILES
mitkIPythonService.cpp
mitkPythonActivator.cpp
mitkPythonService.cpp
QmitkCtkPythonShell.cpp
QmitkPythonVariableStackTableModel.cpp
QmitkPythonVariableStackTableView.cpp
QmitkPythonScriptEditorHighlighter.cpp
QmitkPythonTextEditor.cpp
QmitkPythonSnippets.cpp
)
+if(BUILD_TESTING)
+ SET(H_FILES
+ Testing/mitkCommonPythonTest.h
+ )
+endif()
+
#SET(UI_FILES
# QmitkPythonSnippets.ui
#)
SET(MOC_H_FILES
QmitkCtkPythonShell.h
QmitkPythonVariableStackTableModel.h
QmitkPythonVariableStackTableView.h
QmitkPythonScriptEditorHighlighter.h
QmitkPythonTextEditor.h
QmitkPythonSnippets.h
)
set(QRC_FILES
resources/mitkPython.qrc
)
diff --git a/Modules/Python/mitkIPythonService.h b/Modules/Python/mitkIPythonService.h
index ddde271380..d9af572e60 100644
--- a/Modules/Python/mitkIPythonService.h
+++ b/Modules/Python/mitkIPythonService.h
@@ -1,141 +1,141 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkIPythonService_h
#define mitkIPythonService_h
// mitk
#include
#include "mitkImage.h"
//for microservices
#include
#include "mitkSurface.h"
#include
namespace mitk
{
///
/// describes a python variable (data container)
/// \see IPythonService::GetVariableStack()
///
struct PythonVariable
{
std::string m_Name;
std::string m_Type;
std::string m_Value;
};
///
/// a PythonCommandObserver gets informed as soon as a python command was issued
/// \see IPythonService::AddPythonCommandObserver()
///
class PythonCommandObserver
{
public:
virtual void CommandExecuted(const std::string& pythonCommand) = 0;
};
///
/// The central service for issuing Python Code
/// The class also enables to transfer mitk images to python as itk::Image and vice versa
/// \see IPythonService::GetVariableStack()
///
class MITK_PYTHON_EXPORT IPythonService
{
public:
///
/// Constant representing a single line command
/// \see IPythonService::Execute()
static const int SINGLE_LINE_COMMAND = 0;
///
/// Constant representing a command in which the commands are seperated by new lines, i.e. "\\n"
/// \see IPythonService::Execute()
static const int MULTI_LINE_COMMAND = 1;
///
/// Constant representing a single line command x which is run as "eval(x)"
/// \see IPythonService::Execute()
static const int EVAL_COMMAND = 2;
///
/// Executes a python command.
/// \return A variant containing the return value as string of the python code (if any)
virtual std::string Execute( const std::string& pythonCommand, int commandType = SINGLE_LINE_COMMAND ) = 0;
///
/// Executes a python script.
virtual void ExecuteScript( const std::string& pathToPythonScript ) = 0;
///
/// \return true if the last call to Execute...() resulted in an error, false otherwise
virtual bool PythonErrorOccured() const = 0;
///
/// \return The list of variables in the __main__ namespace
virtual std::vector GetVariableStack() const = 0;
///
/// \return true if a variable with this name is defined in the __main__ namespace, false otherwise
virtual bool DoesVariableExist(const std::string& name) const = 0;
///
/// adds a command observer which is informed after a command was issued with "Execute"
virtual void AddPythonCommandObserver( PythonCommandObserver* observer ) = 0;
///
/// removes a specific command observer
virtual void RemovePythonCommandObserver( PythonCommandObserver* observer ) = 0;
///
/// notify all observer. this should only be used if it can be garantueed that the
/// current python interpreter instance got another command from anywhere else
/// the the Execute() method of this service, e.g. the shell widget uses this function
/// since it does not use Execute()
virtual void NotifyObserver( const std::string& command ) = 0;
///
/// \return true, if itk wrapping is available, false otherwise
- virtual bool IsItkPythonWrappingAvailable() = 0;
+ virtual bool IsSimpleItkPythonWrappingAvailable() = 0;
///
/// copies an mitk image as itk image into the python interpreter process
/// the image will be available as "varName" in python if everythin worked
/// \return true if image was copied, else false
- virtual bool CopyToPythonAsItkImage( mitk::Image* image, const std::string& varName ) = 0;
+ virtual bool CopyToPythonAsSimpleItkImage( mitk::Image* image, const std::string& varName ) = 0;
///
/// copies an itk image from the python process that is named "varName"
/// \return the image or 0 if copying was not possible
- virtual mitk::Image::Pointer CopyItkImageFromPython( const std::string& varName ) = 0;
+ virtual mitk::Image::Pointer CopySimpleItkImageFromPython( const std::string& varName ) = 0;
///
/// \return true, if OpenCv wrapping is available, false otherwise
virtual bool IsOpenCvPythonWrappingAvailable() = 0;
///
/// \see CopyToPythonAsItkImage()
virtual bool CopyToPythonAsCvImage( mitk::Image* image, const std::string& varName ) = 0;
///
/// \see CopyCvImageFromPython()
virtual mitk::Image::Pointer CopyCvImageFromPython( const std::string& varName ) = 0;
///
/// \return true, if vtk wrapping is available, false otherwise
virtual bool IsVtkPythonWrappingAvailable() = 0;
///
/// \see CopyToPythonAsItkImage()
virtual bool CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& varName ) = 0;
///
/// \see CopyCvImageFromPython()
virtual mitk::Surface::Pointer CopyVtkPolyDataFromPython( const std::string& varName ) = 0;
///
/// nothing to do here
virtual ~IPythonService(); // leer in mitkIPythonService.cpp implementieren
};
}
US_DECLARE_SERVICE_INTERFACE(mitk::IPythonService, "org.mitk.services.IPythonService")
#endif
diff --git a/Modules/Python/mitkPythonService.cpp b/Modules/Python/mitkPythonService.cpp
index df84c3fef3..da852eab10 100644
--- a/Modules/Python/mitkPythonService.cpp
+++ b/Modules/Python/mitkPythonService.cpp
@@ -1,529 +1,646 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkPythonService.h"
#include
#include
#include
#include
#include
#include "PythonPath.h"
+#include
+#include
+#include
+#include
+#include
+
+#ifndef WIN32
+ #include
+#endif
const QString mitk::PythonService::m_TmpDataFileName("temp_mitk_data_file");
+#ifdef USE_MITK_BUILTIN_PYTHON
+ static char* pHome = NULL;
+#endif
mitk::PythonService::PythonService()
: m_ItkWrappingAvailable( true ), m_OpenCVWrappingAvailable( true ), m_VtkWrappingAvailable( true ), m_ErrorOccured( false )
{
{
MITK_DEBUG << "will init python if necessary";
}
bool pythonInitialized = static_cast( Py_IsInitialized() ); //m_PythonManager.isPythonInitialized() );
{
MITK_DEBUG << "pythonInitialized " << pythonInitialized;
MITK_DEBUG << "m_PythonManager.isPythonInitialized() " << m_PythonManager.isPythonInitialized();
}
// due to strange static var behaviour on windows Py_IsInitialized() returns correct value while
// m_PythonManager.isPythonInitialized() does not because it has been constructed and destructed again
if( !m_PythonManager.isPythonInitialized() )
{
try
{
+//TODO a better way to do this
+#ifndef WIN32
+#if defined (__APPLE__) || defined(MACOSX)
+ const char* library = "libpython2.7.dylib";
+#else
+ const char* library = "libpython2.7.so";
+#endif
+ dlerror();
+ if(dlopen(library, RTLD_NOW | RTLD_GLOBAL) == 0 )
+ {
+ mitkThrow() << "Python runtime could not be loaded: " << dlerror();
+ }
+#endif
+
+ std::string programPath = mitk::IOUtil::GetProgramPath();
+ QDir programmDir( QString( programPath.c_str() ).append("/Python") );
+ QString pythonCommand;
+ // Set the pythonpath variable depending if
+ // we have an installer or development environment
+ if ( programmDir.exists() ) {
+ // runtime directory used in installers
+ pythonCommand.append( QString("import site, sys\n") );
+ pythonCommand.append( QString("sys.path.append('')\n") );
+ pythonCommand.append( QString("sys.path.append('%1')\n").arg(programPath.c_str()) );
+ pythonCommand.append( QString("sys.path.append('%1/Python')").arg(programPath.c_str()) );
+#ifndef USE_MITK_BUILTIN_PYTHON
+ pythonCommand.append( QString("\nsite.addsitedir('%1/Python/SimpleITK')").arg(programPath.c_str()) );
+#endif
+ } else {
+ pythonCommand.append(PYTHONPATH_COMMAND);
+ }
+
if( pythonInitialized )
m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut|PythonQt::PythonAlreadyInitialized);
else
m_PythonManager.setInitializationFlags(PythonQt::RedirectStdOut);
- MITK_DEBUG("PythonService") << "initalizing python";
- m_PythonManager.initialize();
-
- MITK_DEBUG("PythonService") << "python initalized";
+// set python home if own runtime is used
+#ifdef USE_MITK_BUILTIN_PYTHON
+ QString pythonHome;
+ if ( programmDir.exists() )
+ pythonHome.append(QString("%1/Python").arg(programPath.c_str()));
+ else
+ pythonHome.append(PYTHONHOME);
- QString pythonCommand(PYTHONPATH_COMMAND);
- MITK_DEBUG("PythonService") << "registering python paths" << PYTHONPATH_COMMAND;
- m_PythonManager.executeString( pythonCommand, ctkAbstractPythonManager::FileInput );
+ if(pHome) delete[] pHome;
+ pHome = new char[pythonHome.toStdString().length() + 1];
- /*
- //system("export LD_LIBRARY_PATH=/local/muellerm/mitk/bugsquashing/bin-debug/VTK-build/bin:$LD_LIBRARY_PATH");
- //m_PythonManager.executeString( "print sys.path", ctkAbstractPythonManager::SingleInput );
- //MITK_DEBUG("mitk::PythonService") << "result of 'sys.path': " << result.toString().toStdString();
+ strcpy(pHome,pythonHome.toStdString().c_str());
+ Py_SetPythonHome(pHome);
+ MITK_DEBUG("PythonService") << "PythonHome: " << pHome;
+#endif
- //m_PythonManager.executeString( "sys.path.append('/usr/share/pyshared/numpy')", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "import numpy", ctkAbstractPythonManager::SingleInput );
+ MITK_DEBUG("PythonService") << "initalizing python";
+ m_PythonManager.initialize();
- MITK_DEBUG("mitk::PythonService") << "Trying to import ITK";
- m_PythonManager.executeString( "import itk", ctkAbstractPythonManager::SingleInput );
- m_ItkWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_ItkWrappingAvailable: " << (m_ItkWrappingAvailable? "yes": "no");
- if( !m_ItkWrappingAvailable )
+#ifdef USE_MITK_BUILTIN_PYTHON
+ PyObject* dict = PyDict_New();
+ // Import builtin modules
+ if (PyDict_GetItemString(dict, "__builtins__") == NULL)
{
- MITK_WARN << "ITK Python wrapping not available. Please check build settings or PYTHONPATH settings.";
+ PyObject* builtinMod = PyImport_ImportModule("__builtin__");
+ if (builtinMod == NULL ||
+ PyDict_SetItemString(dict, "__builtins__", builtinMod) != 0)
+ {
+ Py_DECREF(dict);
+ Py_XDECREF(dict);
+ return;
+ }
+ Py_DECREF(builtinMod);
}
+#endif
- {
- MITK_DEBUG("mitk::PythonService") << "Trying to import OpenCv";
- PyRun_SimpleString("import cv2\n");
- if (PyErr_Occurred())
- {
- PyErr_Print();
- }
- else
- m_OpenCVWrappingAvailable = true;
-
- //m_PythonManager.executeString( "import cv2", ctkAbstractPythonManager::SingleInput );
- MITK_DEBUG("mitk::PythonService") << "Investigate if an error occured while importing cv2";
- //m_OpenCVWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_OpenCVWrappingAvailable: " << (m_OpenCVWrappingAvailable? "yes": "no");
- if( !m_OpenCVWrappingAvailable )
- {
- MITK_WARN << "OpenCV Python wrapping not available. Please check build settings or PYTHONPATH settings.";
- }
- }
+ MITK_DEBUG("PythonService")<< "Python Search paths: " << Py_GetPath();
+ MITK_DEBUG("PythonService") << "python initalized";
- MITK_DEBUG("mitk::PythonService") << "Trying to import VTK";
- m_PythonManager.executeString( "import vtk", ctkAbstractPythonManager::SingleInput );
- m_VtkWrappingAvailable = !m_PythonManager.pythonErrorOccured();
- MITK_DEBUG("mitk::PythonService") << "m_VtkWrappingAvailable: " << (m_VtkWrappingAvailable? "yes": "no");
- if( !m_VtkWrappingAvailable )
- {
- MITK_WARN << "VTK Python wrapping not available. Please check build settings or PYTHONPATH settings.";
- }
- */
+ MITK_DEBUG("PythonService") << "registering python paths" << PYTHONPATH_COMMAND;
+ m_PythonManager.executeString( pythonCommand, ctkAbstractPythonManager::FileInput );
}
catch (...)
{
MITK_DEBUG("PythonService") << "exception initalizing python";
}
-
}
-
- //m_PythonManager.executeString( "for path in sys.path:\n print path\n", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "for k, v in os.environ.items():\n print \"%s=%s\" % (k, v)", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeFile("/local/muellerm/Dropbox/13-02-11-python-wrapping/interpreterInfo.py");
- //std::string result = m_PythonManager.executeString( "5+5", ctkAbstractPythonManager::EvalInput );
- //MITK_DEBUG("mitk::PythonService") << "result of '5+5': " << result.toString().toStdString();
}
mitk::PythonService::~PythonService()
{
- //QVariant result = m_PythonManager.executeString( "sys.getrefcount(cv2)", ctkAbstractPythonManager::EvalInput );
- //MITK_DEBUG("mitk::PythonService") << "sys.getrefcount(cv2): " << result.toString().toStdString();
-
- //m_PythonManager.executeString( "del sys.modules[\"cv2\"]", ctkAbstractPythonManager::SingleInput );
- //m_PythonManager.executeString( "del cv2", ctkAbstractPythonManager::SingleInput );
MITK_DEBUG("mitk::PythonService") << "destructing PythonService";
+
+#ifdef USE_MITK_BUILTIN_PYTHON
+ if(pHome)
+ delete[] pHome;
+#endif
}
std::string mitk::PythonService::Execute(const std::string &stdpythonCommand, int commandType)
{
QString pythonCommand = QString::fromStdString(stdpythonCommand);
+ {
+ MITK_DEBUG("mitk::PythonService") << "pythonCommand = " << pythonCommand.toStdString();
+ MITK_DEBUG("mitk::PythonService") << "commandType = " << commandType;
+ }
- {
- MITK_DEBUG("mitk::PythonService") << "pythonCommand = " << pythonCommand.toStdString();
- MITK_DEBUG("mitk::PythonService") << "commandType = " << commandType;
- }
-
- QVariant result;
- bool commandIssued = true;
+ QVariant result;
+ bool commandIssued = true;
- if(commandType == IPythonService::SINGLE_LINE_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput );
- else if(commandType == IPythonService::MULTI_LINE_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput );
- else if(commandType == IPythonService::EVAL_COMMAND )
- result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput );
- else
- commandIssued = false;
+ if(commandType == IPythonService::SINGLE_LINE_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::SingleInput );
+ else if(commandType == IPythonService::MULTI_LINE_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::FileInput );
+ else if(commandType == IPythonService::EVAL_COMMAND )
+ result = m_PythonManager.executeString(pythonCommand, ctkAbstractPythonManager::EvalInput );
+ else
+ commandIssued = false;
- if(commandIssued)
- {
- this->NotifyObserver(pythonCommand.toStdString());
- m_ErrorOccured = PythonQt::self()->hadError();
- }
+ if(commandIssued)
+ {
+ this->NotifyObserver(pythonCommand.toStdString());
+ m_ErrorOccured = PythonQt::self()->hadError();
+ }
- return result.toString().toStdString();
+ return result.toString().toStdString();
}
void mitk::PythonService::ExecuteScript( const std::string& pythonScript )
{
m_PythonManager.executeFile(QString::fromStdString(pythonScript));
}
std::vector mitk::PythonService::GetVariableStack() const
{
- std::vector list;
+ std::vector list;
+
+ PyObject* dict = PyImport_GetModuleDict();
+ PyObject* object = PyDict_GetItemString(dict, "__main__");
+ PyObject* dirMain = PyObject_Dir(object);
+ PyObject* tempObject = 0;
+ PyObject* strTempObject = 0;
- PyObject* dict = PyImport_GetModuleDict();
- PyObject* object = PyDict_GetItemString(dict, "__main__");
- PyObject* dirMain = PyObject_Dir(object);
- PyObject* tempObject = 0;
- PyObject* strTempObject = 0;
+ if(dirMain)
+ {
+ std::string name, attrValue, attrType;
- if(dirMain)
+ for(int i = 0; iob_type->tp_name;
+
+ strTempObject = PyObject_Repr(tempObject);
+ if(strTempObject && ( PyUnicode_Check(strTempObject) || PyString_Check(strTempObject) ) )
+ attrValue = PyString_AsString(strTempObject);
+ else
+ attrValue = "";
- for(int i = 0; iob_type->tp_name;
-
- strTempObject = PyObject_Repr(tempObject);
- if(strTempObject && ( PyUnicode_Check(strTempObject) || PyString_Check(strTempObject) ) )
- attrValue = PyString_AsString(strTempObject);
- else
- attrValue = "";
-
- mitk::PythonVariable var;
- var.m_Name = name;
- var.m_Value = attrValue;
- var.m_Type = attrType;
- list.push_back(var);
- }
+ mitk::PythonVariable var;
+ var.m_Name = name;
+ var.m_Value = attrValue;
+ var.m_Type = attrType;
+ list.push_back(var);
}
+ }
- return list;
+ return list;
}
bool mitk::PythonService::DoesVariableExist(const std::string& name) const
{
bool varExists = false;
std::vector allVars = this->GetVariableStack();
- for(int i = 0; i< allVars.size(); i++)
+ for(unsigned int i = 0; i< allVars.size(); i++)
{
if( allVars.at(i).m_Name == name )
{
varExists = true;
break;
}
}
return varExists;
}
void mitk::PythonService::AddPythonCommandObserver(mitk::PythonCommandObserver *observer)
{
if(!m_Observer.contains(observer))
m_Observer.append(observer);
}
void mitk::PythonService::RemovePythonCommandObserver(mitk::PythonCommandObserver *observer)
{
m_Observer.removeOne(observer);
}
void mitk::PythonService::NotifyObserver(const std::string &command)
{
MITK_DEBUG("mitk::PythonService") << "number of observer " << m_Observer.size();
- for( size_t i=0; i< m_Observer.size(); ++i )
+ for( int i=0; i< m_Observer.size(); ++i )
{
m_Observer.at(i)->CommandExecuted(command);
}
}
QString mitk::PythonService::GetTempDataFileName(const std::string& ext) const
{
QString tmpFolder = QDir::tempPath();
QString fileName = tmpFolder + QDir::separator() + m_TmpDataFileName + QString::fromStdString(ext);
return fileName;
}
-bool mitk::PythonService::CopyToPythonAsItkImage(mitk::Image *image, const std::string &stdvarName)
+bool mitk::PythonService::CopyToPythonAsSimpleItkImage(mitk::Image *image, const std::string &stdvarName)
{
QString varName = QString::fromStdString( stdvarName );
- // save image
- QString fileName = this->GetTempDataFileName( mitk::IOUtil::DEFAULTIMAGEEXTENSION );
- fileName = QDir::fromNativeSeparators( fileName );
-
- MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
- if( !mitk::IOUtil::SaveImage(image, fileName.toStdString()) )
- {
- MITK_ERROR << "Temporary file could not be created.";
- }
- else
+ QString command;
+ unsigned int* imgDim = image->GetDimensions();
+ int npy_nd = 1;
+ npy_intp* npy_dims = new npy_intp[1];
+ npy_dims[0] = imgDim[0] * imgDim[1] * imgDim[2];
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ const mitk::Vector3D spacing = image->GetGeometry()->GetSpacing();
+ const mitk::Point3D origin = image->GetGeometry()->GetOrigin();
+ mitk::PixelType pixelType = image->GetPixelType();
+ itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
+ PyObject* npyArray = NULL;
+ mitk::ImageReadAccessor racc(image);
+ void* array = (void*) racc.GetData();
+
+ // default pixeltype: unsigned short
+ NPY_TYPES npy_type = NPY_USHORT;
+ std::string sitk_type = "sitkUInt8";
+ if( ioPixelType == itk::ImageIOBase::SCALAR )
{
- // TODO CORRECT TYPE SETUP, MAKE MITK_DEBUG("PythonService") MITK_DEBUG("PythonService")
- int dim = image->GetDimension();
- mitk::PixelType pixelType = image->GetPixelType();
- itk::ImageIOBase::IOPixelType ioPixelType = image->GetPixelType().GetPixelType();
-
- // default pixeltype: unsigned short
- QString type = "US";
- if( ioPixelType == itk::ImageIOBase::SCALAR )
- {
- if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE )
- type = "D";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT )
- type = "F";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT)
- type = "SS";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR )
- type = "SC";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::INT )
- type = "SI";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG )
- type = "SL";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR )
- type = "UC";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT )
- type = "UI";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG )
- type = "UL";
- else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT )
- type = "US";
+ if( pixelType.GetComponentType() == itk::ImageIOBase::DOUBLE ) {
+ npy_type = NPY_DOUBLE;
+ sitk_type = "sitkFloat64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::FLOAT ) {
+ npy_type = NPY_FLOAT;
+ sitk_type = "sitkFloat32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::SHORT) {
+ npy_type = NPY_SHORT;
+ sitk_type = "sitkInt16";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::CHAR ) {
+ npy_type = NPY_BYTE;
+ sitk_type = "sitkInt8";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::INT ) {
+ npy_type = NPY_INT;
+ sitk_type = "sitkInt32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::LONG ) {
+ npy_type = NPY_LONG;
+ sitk_type = "sitkInt64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UCHAR ) {
+ npy_type = NPY_UBYTE;
+ sitk_type = "sitkUInt8";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::UINT ) {
+ npy_type = NPY_UINT;
+ sitk_type = "sitkUInt32";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::ULONG ) {
+ npy_type = NPY_LONG;
+ sitk_type = "sitkUInt64";
+ } else if( pixelType.GetComponentType() == itk::ImageIOBase::USHORT ) {
+ npy_type = NPY_USHORT;
+ sitk_type = "sitkUInt16";
}
+ } else {
+ MITK_WARN << "not a scalar pixeltype";
+ return false;
+ }
- MITK_DEBUG("PythonService") << "Got mitk image with type " << type.toStdString() << " and dim " << dim;
-
- QString command;
-
- command.append( QString("imageType = itk.Image[itk.%1, %2]\n") .arg( type ).arg( dim ) );
-
- command.append( QString("readerType = itk.ImageFileReader[imageType]\n") );
- command.append( QString("reader = readerType.New()\n") );
- command.append( QString("reader.SetFileName( \"%1\" )\n") .arg(fileName) );
- command.append( QString("reader.Update()\n") );
- command.append( QString("%1 = reader.GetOutput()\n").arg( varName ) );
+ // creating numpy array
+ import_array1 (true);
+ npyArray = PyArray_SimpleNewFromData(npy_nd,npy_dims,npy_type,array);
+
+ // add temp array it to the python dictionary to access it in python code
+ const int status = PyDict_SetItemString( pyDict,QString("%1_numpy_array")
+ .arg(varName).toStdString().c_str(),
+ npyArray );
+
+ // sanity check
+ if ( status != 0 )
+ return false;
+
+ command.append( QString("%1 = sitk.Image(%2,%3,%4,sitk.%5)\n").arg(varName)
+ .arg(QString::number(imgDim[0]))
+ .arg(QString::number(imgDim[1]))
+ .arg(QString::number(imgDim[2]))
+ .arg(QString(sitk_type.c_str())) );
+ command.append( QString("%1.SetSpacing([%2,%3,%4])\n").arg(varName)
+ .arg(QString::number(spacing[0]))
+ .arg(QString::number(spacing[1]))
+ .arg(QString::number(spacing[2])) );
+ command.append( QString("%1.SetOrigin([%2,%3,%4])\n").arg(varName)
+ .arg(QString::number(origin[0]))
+ .arg(QString::number(origin[1]))
+ .arg(QString::number(origin[2])) );
+ // directly access the cpp api from the lib
+ command.append( QString("_SimpleITK._SetImageFromArray(%1_numpy_array,%1)\n").arg(varName) );
+ command.append( QString("del %1_numpy_array").arg(varName) );
- MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
- MITK_INFO << this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute( command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- QFile file( fileName );
- MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
- file.remove();
- return true;
- }
- return false;
+ return true;
}
-mitk::Image::Pointer mitk::PythonService::CopyItkImageFromPython(const std::string &stdvarName)
+mitk::Image::Pointer mitk::PythonService::CopySimpleItkImageFromPython(const std::string &stdvarName)
{
+ double*ds = NULL;
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ mitk::Image::Pointer mitkImage = mitk::Image::New();
+ mitk::Vector3D spacing;
+ mitk::Point3D origin;
+ QString command;
QString varName = QString::fromStdString( stdvarName );
- mitk::Image::Pointer mitkImage;
- QString command;
- QString fileName = GetTempDataFileName( mitk::IOUtil::DEFAULTIMAGEEXTENSION );
- fileName = QDir::fromNativeSeparators( fileName );
- MITK_DEBUG("PythonService") << "Saving temporary file with python itk code " << fileName.toStdString();
+ command.append( QString("%1_numpy_array = sitk.GetArrayFromImage(%1)\n").arg(varName) );
+ command.append( QString("%1_spacing = numpy.asarray(%1.GetSpacing())\n").arg(varName) );
+ command.append( QString("%1_origin = numpy.asarray(%1.GetOrigin())\n").arg(varName) );
+ command.append( QString("%1_dtype = %1_numpy_array.dtype.name").arg(varName) );
- command.append( QString( "writer = itk.ImageFileWriter[ %1 ].New()\n").arg( varName ) );
- command.append( QString( "writer.SetFileName( \"%1\" )\n").arg(fileName) );
- command.append( QString( "writer.SetInput( %1 )\n").arg(varName) );
- command.append( QString( "writer.Update()\n" ) );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
- this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+ PyObject* py_dtype = PyDict_GetItemString(pyDict,QString("%1_dtype").arg(varName).toStdString().c_str() );
+ std::string dtype = PyString_AsString(py_dtype);
+ PyArrayObject* py_data = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_numpy_array").arg(varName).toStdString().c_str() );
+ PyArrayObject* py_spacing = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_spacing").arg(varName).toStdString().c_str() );
+ PyArrayObject* py_origin = (PyArrayObject*) PyDict_GetItemString(pyDict,QString("%1_origin").arg(varName).toStdString().c_str() );
+
+ size_t sz = sizeof(short);
+ mitk::PixelType pixelType = MakeScalarPixelType();
+ if( dtype.compare("float64") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(double);
+ } else if( dtype.compare("float32") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(float);
+ } else if( dtype.compare("int16") == 0) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(short);
+ } else if( dtype.compare("int8") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(char);
+ } else if( dtype.compare("int32") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(int);
+ } else if( dtype.compare("int64") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(long);
+ } else if( dtype.compare("uint8") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(unsigned char);
+ } else if( dtype.compare("uint32") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(unsigned int);
+ } else if( dtype.compare("uint64") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(unsigned long);
+ } else if( dtype.compare("uint16") == 0 ) {
+ pixelType = MakeScalarPixelType();
+ sz = sizeof(unsigned short);
+ }
- try
- {
- MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK image";
- mitkImage = mitk::IOUtil::LoadImage( fileName.toStdString() );
- }
- catch(std::exception& e)
- {
- MITK_ERROR << e.what();
- }
+ unsigned int* dimensions = new unsigned int[py_data->nd];
+ // fill backwards , nd data saves dimensions in opposite direction
+ for( int i = 0; i < py_data->nd; ++i )
+ {
+ dimensions[i] = py_data->dimensions[py_data->nd - 1 - i];
+ sz *= dimensions[i];
+ }
- QFile file(fileName);
- if( file.exists() )
- {
- MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
- file.remove();
- }
+ mitkImage->Initialize(pixelType, py_data->nd, dimensions);
+ mitkImage->SetChannel(py_data->data);
+
+ ds = (double*)py_spacing->data;
+ spacing[0] = ds[0];
+ spacing[1] = ds[1];
+ spacing[2] = ds[2];
+ mitkImage->GetGeometry()->SetSpacing(spacing);
+
+ ds = (double*)py_origin->data;
+ origin[0] = ds[0];
+ origin[1] = ds[1];
+ origin[2] = ds[2];
+ mitkImage->GetGeometry()->SetOrigin(origin);
+
+ // cleanup
+ command.clear();
+ command.append( QString("del %1_numpy_array\n").arg(varName) );
+ command.append( QString("del %1_dtype\n").arg(varName) );
+ command.append( QString("del %1_spacing\n").arg(varName) );
+ command.append( QString("del %1_origin").arg(varName) );
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
+
+ delete[] dimensions;
- return mitkImage;
+ return mitkImage;
}
bool mitk::PythonService::CopyToPythonAsCvImage( mitk::Image* image, const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
bool convert = false;
if(image->GetDimension() != 2)
{
MITK_ERROR << "Only 2D images allowed for OpenCV images";
return convert;
}
// try to save mitk image
QString fileName = this->GetTempDataFileName( ".bmp" );
fileName = QDir::fromNativeSeparators( fileName );
MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
if( !mitk::IOUtil::SaveImage(image, fileName.toStdString()) )
{
MITK_ERROR << "Temporary file " << fileName.toStdString() << " could not be created.";
return convert;
}
QString command;
command.append( QString("%1 = cv2.imread(\"%2\")\n") .arg( varName ).arg( fileName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
QFile file(fileName);
file.remove();
convert = true;
return convert;
}
mitk::Image::Pointer mitk::PythonService::CopyCvImageFromPython( const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
mitk::Image::Pointer mitkImage;
QString command;
QString fileName = GetTempDataFileName( ".bmp" );
fileName = QDir::fromNativeSeparators( fileName );
MITK_DEBUG("PythonService") << "run python command to save image with opencv to " << fileName.toStdString();
command.append( QString( "cv2.imwrite(\"%1\", %2)\n").arg( fileName ).arg( varName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
try
{
MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK image";
mitkImage = mitk::IOUtil::LoadImage( fileName.toStdString() );
}
catch(std::exception& e)
{
MITK_ERROR << e.what();
}
QFile file(fileName);
if( file.exists() )
{
MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
file.remove();
}
return mitkImage;
}
ctkAbstractPythonManager *mitk::PythonService::GetPythonManager()
{
return &m_PythonManager;
}
mitk::Surface::Pointer mitk::PythonService::CopyVtkPolyDataFromPython( const std::string& stdvarName )
{
- QString varName = QString::fromStdString( stdvarName );
- mitk::Surface::Pointer newSurface;
-
+ // access python module
+ PyObject *pyMod = PyImport_AddModule((char*)"__main__");
+ // global dictionarry
+ PyObject *pyDict = PyModule_GetDict(pyMod);
+ // python memory address
+ PyObject *pyAddr = NULL;
+ // cpp address
+ size_t addr = 0;
+ mitk::Surface::Pointer surface = mitk::Surface::New();
QString command;
- QString fileName = GetTempDataFileName( ".stl" );
- fileName = QDir::fromNativeSeparators( fileName );
+ QString varName = QString::fromStdString( stdvarName );
- MITK_DEBUG("PythonService") << "run python command to save polydata with vtk to " << fileName.toStdString();
- command = QString (
- "vtkStlWriter = vtk.vtkSTLWriter()\n"
- "vtkStlWriter.SetInput(%1)\n"
- "vtkStlWriter.SetFileName(\"%2\")\n"
- "vtkStlWriter.Write()\n").arg(varName).arg(fileName);
+ command.append( QString("%1_addr_str = %1.GetAddressAsString(\"vtkPolyData\")\n").arg(varName) );
+ // remove 0x from the address
+ command.append( QString("%1_addr = int(%1_addr_str[5:],16)").arg(varName) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- try
- {
- MITK_DEBUG("PythonService") << "Loading temporary file " << fileName.toStdString() << " as MITK Surface";
- newSurface = mitk::IOUtil::LoadSurface( fileName.toStdString() );
- }
- catch(std::exception& e)
- {
- MITK_ERROR << e.what();
- }
+ // get address of the object
+ pyAddr = PyDict_GetItemString(pyDict,QString("%1_addr").arg(varName).toStdString().c_str());
- QFile file(fileName);
- if( file.exists() )
- {
- MITK_DEBUG("PythonService") << "Removing temporary file " << fileName.toStdString();
- file.remove();
- }
+ // convert to long
+ addr = PyInt_AsLong(pyAddr);
+
+ MITK_DEBUG << "Python object address: " << addr;
+
+ // get the object
+ vtkPolyData* poly = (vtkPolyData*)((void*)addr);
+ surface->SetVtkPolyData(poly);
+
+ // delete helper variables from python stack
+ command = "";
+ command.append( QString("del %1_addr_str\n").arg(varName) );
+ command.append( QString("del %1_addr").arg(varName) );
+
+ MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
+ this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- return newSurface;
+ return surface;
}
bool mitk::PythonService::CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& stdvarName )
{
QString varName = QString::fromStdString( stdvarName );
- bool convert = false;
+ std::ostringstream oss;
+ std::string addr = "";
+ QString command;
+ QString address;
- // try to save mitk image
- QString fileName = this->GetTempDataFileName( ".stl" );
- fileName = QDir::fromNativeSeparators( fileName );
- MITK_DEBUG("PythonService") << "Saving temporary file " << fileName.toStdString();
- if( !mitk::IOUtil::SaveSurface( surface, fileName.toStdString() ) )
- {
- MITK_ERROR << "Temporary file " << fileName.toStdString() << " could not be created.";
- return convert;
- }
+ oss << (void*) ( surface->GetVtkPolyData() );
- QString command;
+ // get the address
+ addr = oss.str();
+
+ // remove "0x"
+ address = QString::fromStdString(addr.substr(2));
+
+ command.append( QString("%1 = vtk.vtkPolyData(\"%2\")\n").arg(varName).arg(address) );
- command.append( QString("vtkStlReader = vtk.vtkSTLReader()\n") );
- command.append( QString("vtkStlReader.SetFileName(\"%1\")\n").arg( fileName ) );
- command.append( QString("vtkStlReader.Update()\n") );
- command.append( QString("%1 = vtkStlReader.GetOutput()\n").arg( varName ) );
MITK_DEBUG("PythonService") << "Issuing python command " << command.toStdString();
this->Execute(command.toStdString(), IPythonService::MULTI_LINE_COMMAND );
- MITK_DEBUG("PythonService") << "Removing file " << fileName.toStdString();
- QFile file(fileName);
- file.remove();
- convert = true;
- return convert;
+ return true;
}
-bool mitk::PythonService::IsItkPythonWrappingAvailable()
+bool mitk::PythonService::IsSimpleItkPythonWrappingAvailable()
{
- this->Execute( "import itk\n", IPythonService::SINGLE_LINE_COMMAND );
- this->Execute( "print \"Using ITK version \" + itk.Version.GetITKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
+ this->Execute( "import SimpleITK as sitk\n", IPythonService::SINGLE_LINE_COMMAND );
+ // directly access cpp lib
+ this->Execute( "import _SimpleITK\n", IPythonService::SINGLE_LINE_COMMAND );
+ m_ItkWrappingAvailable = !this->PythonErrorOccured();
+
+ // check for numpy
+ this->Execute( "import numpy\n", IPythonService::SINGLE_LINE_COMMAND );
+
+ if ( this->PythonErrorOccured() )
+ MITK_ERROR << "Numpy not found.";
m_ItkWrappingAvailable = !this->PythonErrorOccured();
return m_ItkWrappingAvailable;
}
bool mitk::PythonService::IsOpenCvPythonWrappingAvailable()
{
this->Execute( "import cv2\n", IPythonService::SINGLE_LINE_COMMAND );
m_OpenCVWrappingAvailable = !this->PythonErrorOccured();
return m_OpenCVWrappingAvailable;
}
bool mitk::PythonService::IsVtkPythonWrappingAvailable()
{
this->Execute( "import vtk", IPythonService::SINGLE_LINE_COMMAND );
- this->Execute( "print \"Using VTK version \" + vtk.vtkVersion.GetVTKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
+ //this->Execute( "print \"Using VTK version \" + vtk.vtkVersion.GetVTKVersion()\n", IPythonService::SINGLE_LINE_COMMAND );
m_VtkWrappingAvailable = !this->PythonErrorOccured();
return m_VtkWrappingAvailable;
}
bool mitk::PythonService::PythonErrorOccured() const
{
return m_ErrorOccured;
}
diff --git a/Modules/Python/mitkPythonService.h b/Modules/Python/mitkPythonService.h
index a566b8214d..37f1b34d0d 100644
--- a/Modules/Python/mitkPythonService.h
+++ b/Modules/Python/mitkPythonService.h
@@ -1,105 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkPythonService_h
#define mitkPythonService_h
#include "mitkIPythonService.h"
#include
#include
#include "mitkSurface.h"
#include
namespace mitk
{
///
/// implementation of the IPythonService using ctkabstractpythonmanager
/// \see IPythonService
class MITK_PYTHON_EXPORT PythonService: public itk::LightObject, public mitk::IPythonService
{
public:
///
/// instantiate python manager here
PythonService();
///
/// empty implementation...
~PythonService();
///
/// \see IPythonService::Execute()
std::string Execute( const std::string& pythonCommand, int commandType = SINGLE_LINE_COMMAND );
///
/// \see IPythonService::ExecuteScript()
void ExecuteScript(const std::string &pathToPythonScript);
///
/// \see IPythonService::PythonErrorOccured()
bool PythonErrorOccured() const;
///
/// \see IPythonService::GetVariableStack()
std::vector GetVariableStack() const;
///
/// \see IPythonService::DoesVariableExist()
bool DoesVariableExist(const std::string& name) const;
///
/// \see IPythonService::AddPythonCommandObserver()
void AddPythonCommandObserver( PythonCommandObserver* observer );
///
/// \see IPythonService::RemovePythonCommandObserver()
void RemovePythonCommandObserver( PythonCommandObserver* observer );
///
/// \see IPythonService::NotifyObserver()
void NotifyObserver( const std::string& command );
///
/// \see IPythonService::IsItkPythonWrappingAvailable()
- bool IsItkPythonWrappingAvailable();
+ bool IsSimpleItkPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsItkImage()
- bool CopyToPythonAsItkImage( mitk::Image* image, const std::string& varName );
+ bool CopyToPythonAsSimpleItkImage( mitk::Image* image, const std::string& varName );
///
/// \see IPythonService::CopyItkImageFromPython()
- mitk::Image::Pointer CopyItkImageFromPython( const std::string& varName );
+ mitk::Image::Pointer CopySimpleItkImageFromPython( const std::string& varName );
///
/// \see IPythonService::IsOpenCvPythonWrappingAvailable()
bool IsOpenCvPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsCvImage()
bool CopyToPythonAsCvImage( mitk::Image* image, const std::string& varName );
///
/// \see IPythonService::CopyCvImageFromPython()
mitk::Image::Pointer CopyCvImageFromPython( const std::string& varName );
///
/// \see IPythonService::IsVtkPythonWrappingAvailable()
bool IsVtkPythonWrappingAvailable();
///
/// \see IPythonService::CopyToPythonAsVtkPolyData()
bool CopyToPythonAsVtkPolyData( mitk::Surface* surface, const std::string& varName );
///
/// \see IPythonService::CopyVtkPolyDataFromPython()
mitk::Surface::Pointer CopyVtkPolyDataFromPython( const std::string& varName );
///
/// \return the ctk abstract python manager instance
ctkAbstractPythonManager* GetPythonManager();
protected:
QString GetTempDataFileName(const std::string &ext) const;
private:
QList m_Observer;
ctkAbstractPythonManager m_PythonManager;
static const QString m_TmpDataFileName;
bool m_ItkWrappingAvailable;
bool m_OpenCVWrappingAvailable;
bool m_VtkWrappingAvailable;
bool m_ErrorOccured;
};
}
#endif
diff --git a/Modules/Python/resources/PythonSnippets.xml b/Modules/Python/resources/PythonSnippets.xml
index a301307dd3..7e8a1bcb5d 100644
--- a/Modules/Python/resources/PythonSnippets.xml
+++ b/Modules/Python/resources/PythonSnippets.xml
@@ -1,7 +1,7 @@
-
-
+
+
diff --git a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png
new file mode 100644
index 0000000000..befab56719
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/MitkPythonPluginView.png differ
diff --git a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
index d1ab3c52fe..0696c4eed9 100644
--- a/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
+++ b/Plugins/org.mitk.gui.qt.python/documentation/UserManual/QmitkPython.dox
@@ -1,10 +1,35 @@
/**
\page org_mitk_gui_qt_python The Python Plugin
Available sections:
- \ref org_mitk_gui_qt_pythonOverview
+ - \ref org_mitk_gui_qt_pythonUsage
+ - \ref org_mitk_gui_qt_PythonConsole
+ - \ref org_mitk_gui_qt_PythonSnippets
\section org_mitk_gui_qt_pythonOverview Overview
The Python view provides the graphical front end to run Python code through the mitkPython module. Furthermore the ITK/VTK/OpenCV Python wrapping can be used.
+Images and surfaces in the DataManager can be transferred via a drag & drop mechanism into the MITK Python Console.
+
+\section org_mitk_gui_qt_pythonUsage Transfer data
+Images and surfaces can be tranferred from the data manger into the python console. To transfer an image or
+surface simply drag it from the data manager into the Variable Stack view, as shown in Figure.
+A new entry will appear in the Variable Stack, as soon as the data is transferred. As soon as the
+entry is available the object can be accessed and modified in the python console. Three dimensional
+images will be copied in-memory to python via numpy and a SimpleITK image object is created with the
+same properties. When a two dimensional image is transferred the user can choose to transfer it as an OpenCV
+image object. Surfaces are fully memory mapped as a vtkPolyData object. To transfer an image or surface
+from the python runtime to the data manager just double click on the corresponding entry in the Variable Stack View.
+
+\imageMacro{QmitkPythonView.png,"Screenshot of the MITK Python Plugin",20}
+
+\section org_mitk_gui_qt_PythonConsole
+The Python console can be used for interactive programming. All items in the data storage can be accessed
+in the python console. The console can also be used to load python scripts and run them.
+
+\section org_mitk_gui_qt_PythonSnippets
+The python plugin contains some code snippets of SimpleITK/VTK/OpenCV that can be run in the python console.
+Snippets can be modified and saved by the user.
+
*/
diff --git a/SuperBuild.cmake b/SuperBuild.cmake
index bf9eaecd94..c314290dca 100644
--- a/SuperBuild.cmake
+++ b/SuperBuild.cmake
@@ -1,454 +1,483 @@
#-----------------------------------------------------------------------------
# Convenient macro allowing to download a file
#-----------------------------------------------------------------------------
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()
#-----------------------------------------------------------------------------
# Qt options for external projects and MITK
#-----------------------------------------------------------------------------
if(MITK_USE_QT)
set(qt_project_args -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION})
else()
set(qt_project_args )
endif()
if(MITK_USE_Qt4)
list(APPEND qt_project_args
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} )
endif()
#-----------------------------------------------------------------------------
# ExternalProjects
#-----------------------------------------------------------------------------
set(external_projects
+ ZLIB
+ Python
+ Numpy
tinyxml
GLUT
ANN
CppUnit
GLEW
VTK
ACVD
GDCM
- CableSwig
OpenCV
Poco
ITK
Boost
DCMTK
CTK
SOFA
MITKData
Qwt
+ PCRE
+ Swig
+ SimpleITK
)
# Qxt supports Qt5. We need to also support it in QxtCMakeLists.txt
#if(MITK_USE_Qt4)
list(APPEND external_projects Qxt)
#endif()
# These are "hard" dependencies and always set to ON
set(MITK_USE_tinyxml 1)
set(MITK_USE_ANN 1)
set(MITK_USE_GLEW 1)
set(MITK_USE_GDCM 1)
set(MITK_USE_ITK 1)
set(MITK_USE_VTK 1)
# Semi-hard dependencies, enabled by user-controlled variables
-set(MITK_USE_CableSwig ${MITK_USE_Python})
if(MITK_USE_QT)
set(MITK_USE_Qwt 1)
#if(MITK_USE_Qt4)
set(MITK_USE_Qxt 1) #TODO: Check how Qxt builds with Qt 5
#endif()
endif()
if(MITK_USE_SOFA)
set(MITK_USE_GLUT 1)
endif()
+if(NOT MITK_USE_SYSTEM_PYTHON)
+ set(MITK_USE_ZLIB 1)
+endif()
+
+if(MITK_USE_SimpleITK OR MITK_USE_Python)
+ set(MITK_USE_SWIG 1)
+ if(UNIX)
+ set(MITK_USE_PCRE 1)
+ endif()
+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)
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()
if(MITK_USE_Boost)
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()
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()
# Look for git early on, if needed
if((BUILD_TESTING AND NOT EXTERNAL_MITK_DATA_DIR) OR
(MITK_USE_CTK AND NOT EXTERNAL_CTK_DIR))
find_package(Git REQUIRED)
endif()
#-----------------------------------------------------------------------------
# External project settings
#-----------------------------------------------------------------------------
include(ExternalProject)
set(ep_base "${CMAKE_BINARY_DIR}/CMakeExternals")
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})
set(ep_install_dir ${ep_base}/Install)
#set(ep_build_dir ${ep_base}/Build)
set(ep_source_dir ${ep_base}/Source)
#set(ep_parallelism_level)
set(ep_build_shared_libs ON)
set(ep_build_testing OFF)
if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL)
set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty)
endif()
# 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()
set(ep_common_args
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir}
-DCMAKE_PREFIX_PATH:PATH=${CMAKE_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}
#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}
)
# 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()
# Include external projects
foreach(p ${external_projects})
include(CMakeExternals/${p}.cmake)
endforeach()
#-----------------------------------------------------------------------------
# Set superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_cmake_boolean_args
BUILD_SHARED_LIBS
WITH_COVERAGE
BUILD_TESTING
MITK_USE_QT
MITK_BUILD_ALL_PLUGINS
MITK_BUILD_ALL_APPS
MITK_BUILD_TUTORIAL # Deprecated. Use MITK_BUILD_EXAMPLES instead
MITK_BUILD_EXAMPLES
MITK_USE_ACVD
MITK_USE_CppUnit
MITK_USE_GLEW
MITK_USE_Boost
MITK_USE_SYSTEM_Boost
MITK_USE_BLUEBERRY
MITK_USE_CTK
MITK_USE_DCMTK
MITK_USE_OpenCV
MITK_USE_Poco
MITK_USE_SOFA
MITK_USE_Python
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
# Mandatory dependencies
${tinyxml_DEPENDS}
${ANN_DEPENDS}
${VTK_DEPENDS}
${ITK_DEPENDS}
# Optionnal dependencies
${ACVD_DEPENDS}
${CppUnit_DEPENDS}
${GLUT_DEPENDS}
${GLEW_DEPENDS}
${Boost_DEPENDS}
${CTK_DEPENDS}
${DCMTK_DEPENDS}
${OpenCV_DEPENDS}
${Poco_DEPENDS}
${SOFA_DEPENDS}
${MITK-Data_DEPENDS}
${Qwt_DEPENDS}
${Qxt_DEPENDS}
+ ${SimpleITK_DEPENDS}
+ ${Numpy_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
+ -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}
+ -DMITK_BUILD_org.mitk.gui.qt.python:BOOL=ON
+ )
+ if( NOT MITK_USE_SYSTEM_PYTHON )
list(APPEND mitk_optional_cache_args
- -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
- -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
- -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
- -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} )
+ # Folders are needed to create an installer
+ -DPython_DIR:PATH=${Python_DIR}
+ -DNumpy_DIR:PATH=${Numpy_DIR}
+ )
+ endif()
endif()
set(proj MITK-Configure)
ExternalProject_Add(${proj}
LIST_SEPARATOR ^^
DOWNLOAD_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_CACHE_ARGS
# --------------- Build options ----------------
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/MITK-build/install
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
# --------------- Compile options ----------------
-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 ---------------
-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}
${qt_project_args}
-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 dirs ---------------
-DMITK_KWSTYLE_EXECUTABLE:FILEPATH=${MITK_KWSTYLE_EXECUTABLE}
-DCTK_DIR:PATH=${CTK_DIR}
-DDCMTK_DIR:PATH=${DCMTK_DIR}
-Dtinyxml_DIR:PATH=${tinyxml_DIR}
-DGLUT_DIR:PATH=${GLUT_DIR}
-DGLEW_DIR:PATH=${GLEW_DIR}
-DANN_DIR:PATH=${ANN_DIR}
-DCppUnit_DIR:PATH=${CppUnit_DIR}
-DVTK_DIR:PATH=${VTK_DIR} # FindVTK expects VTK_DIR
-DITK_DIR:PATH=${ITK_DIR} # FindITK expects ITK_DIR
-DACVD_DIR:PATH=${ACVD_DIR}
-DOpenCV_DIR:PATH=${OpenCV_DIR}
-DPoco_DIR:PATH=${Poco_DIR}
-DSOFA_DIR:PATH=${SOFA_DIR}
-DGDCM_DIR:PATH=${GDCM_DIR}
-DBOOST_ROOT:PATH=${BOOST_ROOT}
-DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES}
-DMITK_DATA_DIR:PATH=${MITK_DATA_DIR}
-DQwt_DIR:PATH=${Qwt_DIR}
-DQxt_DIR:PATH=${Qxt_DIR}
+ -DSimpleITK_DIR:PATH=${SimpleITK_DIR}
+ -DNumpy_DIR:PATH=${Numpy_DIR}
CMAKE_ARGS
${mitk_initial_cache_arg}
${MAC_OSX_ARCHITECTURE_ARGS}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS
MITK-Utilities
)
#-----------------------------------------------------------------------------
# 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
)