diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f9cf77483..9f16412dc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,1076 +1,1082 @@ 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) 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() + # Simulation plugin requires boost chrono library + list(FIND MITK_USE_Boost_LIBRARIES chrono _result) + if(_result LESS 0) + message("Adding 'chrono' to MITK_USE_Boost_LIBRARIES.") + list(APPEND MITK_USE_Boost_LIBRARIES chrono) + endif() set(MITK_USE_Boost_LIBRARIES ${MITK_USE_Boost_LIBRARIES} CACHE STRING "" FORCE) # Allow setting external SOFA plugins directory and SOFA plugins set(MITK_USE_SOFA_PLUGINS_DIR ${MITK_USE_SOFA_PLUGINS_DIR} CACHE PATH "External SOFA plugins directory" FORCE) set(MITK_USE_SOFA_PLUGINS ${MITK_USE_SOFA_PLUGINS} CACHE PATH "List of semicolon-separated plugin names" FORCE) endif() # 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() #----------------------------------------------------------------------------- # 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/Modules/Simulation/CMakeLists.txt b/Modules/Simulation/CMakeLists.txt index 55e9c80660..78ebb99392 100644 --- a/Modules/Simulation/CMakeLists.txt +++ b/Modules/Simulation/CMakeLists.txt @@ -1,11 +1,11 @@ if(MITK_USE_SOFA) MITK_CREATE_MODULE( - DEPENDS MitkCore + DEPENDS MitkSceneSerializationBase PACKAGE_DEPENDS Boost GLUT GLEW SOFA ) if(MSVC) list(APPEND module_compile_flags /wd4250 4251 4267 4275) set_target_properties(${MODULE_TARGET} PROPERTIES COMPILE_FLAGS "${module_compile_flags}") endif() endif() diff --git a/Modules/Simulation/Resources/Interactions/Simulation.xml b/Modules/Simulation/Resources/Interactions/Simulation.xml new file mode 100644 index 0000000000..c0bad251b8 --- /dev/null +++ b/Modules/Simulation/Resources/Interactions/Simulation.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/Simulation/Resources/Interactions/SimulationConfig.xml b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml new file mode 100644 index 0000000000..224f082a55 --- /dev/null +++ b/Modules/Simulation/Resources/Interactions/SimulationConfig.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/Simulation/files.cmake b/Modules/Simulation/files.cmake index d106dec8b4..7f49b08378 100644 --- a/Modules/Simulation/files.cmake +++ b/Modules/Simulation/files.cmake @@ -1,15 +1,30 @@ set(CPP_FILES mitkGetSimulationService.cpp + mitkExportMitkVisitor.cpp mitkIndexROI.cpp mitkISimulationService.cpp + mitkRoundRobinSchedulingAlgorithm.cpp mitkSetVtkRendererVisitor.cpp + mitkSchedulableProcess.cpp + mitkScheduler.cpp + mitkSchedulingAlgorithmBase.cpp mitkSimulation.cpp mitkSimulationActivator.cpp + mitkSimulationInteractor.cpp mitkSimulationIOFactory.cpp mitkSimulationObjectFactory.cpp mitkSimulationReader.cpp + mitkSimulationSerializer.cpp mitkSimulationService.cpp mitkSimulationVtkMapper3D.cpp + mitkSimulationWriter.cpp + mitkSimulationWriterFactory.cpp mitkVtkModel.cpp mitkVtkSimulationPolyDataMapper.cpp + mitkWeightedRoundRobinSchedulingAlgorithm.cpp +) + +set(RESOURCE_FILES + Interactions/Simulation.xml + Interactions/SimulationConfig.xml ) diff --git a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp b/Modules/Simulation/mitkExportMitkVisitor.cpp similarity index 80% rename from Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp rename to Modules/Simulation/mitkExportMitkVisitor.cpp index 121e383aac..4d9ef80592 100644 --- a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.cpp +++ b/Modules/Simulation/mitkExportMitkVisitor.cpp @@ -1,204 +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 "internal/mitkGetDataStorage.h" -#include "internal/mitkGetSimulationDataNode.h" #include "mitkExportMitkVisitor.h" +#include +#include #include #include #include #include #include #include #include static void ApplyMaterial(mitk::DataNode::Pointer dataNode, const sofa::core::loader::Material& material) { using sofa::defaulttype::Vec4f; if (dataNode.IsNull() || dynamic_cast(dataNode->GetData()) == NULL) return; if (material.useDiffuse) dataNode->SetFloatProperty("opacity", material.diffuse[3]); Vec4f ambient = material.useAmbient ? material.ambient : Vec4f(); Vec4f diffuse = material.useDiffuse ? material.diffuse : Vec4f(); Vec4f specular = material.useSpecular ? material.specular : Vec4f(); float shininess = material.useShininess ? std::min(material.shininess, 128.0f) : 45.0f; if (shininess == 0.0f) { specular.clear(); shininess = 1.0f; } dataNode->SetFloatProperty("material.ambientCoefficient", 1.0f); dataNode->SetProperty("material.ambientColor", mitk::ColorProperty::New(material.ambient.elems)); dataNode->SetFloatProperty("material.diffuseCoefficient", 1.0f); dataNode->SetProperty("color", mitk::ColorProperty::New(material.diffuse.elems)); dataNode->SetFloatProperty("material.specularCoefficient", 1.0f); dataNode->SetProperty("material.specularColor", mitk::ColorProperty::New(specular.elems)); dataNode->SetFloatProperty("material.specularPower", shininess); } -mitk::ExportMitkVisitor::ExportMitkVisitor(const sofa::core::ExecParams* params) - : Visitor(params) +static mitk::DataNode::Pointer GetSimulationDataNode(mitk::DataStorage::Pointer dataStorage, sofa::core::objectmodel::BaseNode::SPtr rootNode) +{ + if (dataStorage.IsNull()) + return NULL; + + if (!rootNode) + return NULL; + + mitk::TNodePredicateDataType::Pointer predicate = mitk::TNodePredicateDataType::New(); + mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate); + + for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it) + { + mitk::DataNode::Pointer dataNode = it.Value(); + mitk::Simulation::Pointer simulation = static_cast(dataNode->GetData()); + + if (simulation->GetRootNode() == rootNode) + return dataNode; + } + + return NULL; +} + + +mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params) + : Visitor(params), + m_DataStorage(dataStorage) { } -mitk::ExportMitkVisitor::ExportMitkVisitor(const std::string& visualModelName, const sofa::core::ExecParams* params) +mitk::ExportMitkVisitor::ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params) : Visitor(params), + m_DataStorage(dataStorage), m_VisualModelName(visualModelName) { } mitk::ExportMitkVisitor::~ExportMitkVisitor() { } sofa::simulation::Visitor::Result mitk::ExportMitkVisitor::processNodeTopDown(sofa::simulation::Node* node) { - for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel); - return RESULT_CONTINUE; + if (m_DataStorage.IsNotNull()) + { + for_each(this, node, node->visualModel, &ExportMitkVisitor::processVisualModel); + return RESULT_CONTINUE; + } + + return RESULT_PRUNE; } void mitk::ExportMitkVisitor::processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel) { using sofa::defaulttype::ResizableExtVector; typedef sofa::component::visualmodel::VisualModelImpl::VecCoord VecCoord; typedef sofa::component::visualmodel::VisualModelImpl::Triangle Triangle; typedef sofa::component::visualmodel::VisualModelImpl::Quad Quad; typedef sofa::component::visualmodel::VisualModelImpl::Deriv Deriv; typedef sofa::component::visualmodel::VisualModelImpl::VecTexCoord VecTexCoord; sofa::component::visualmodel::VisualModelImpl* visualModelImpl = dynamic_cast(visualModel); if (visualModelImpl == NULL) return; if (!m_VisualModelName.empty() && m_VisualModelName != visualModelImpl->name.getValue()) return; - DataStorage::Pointer dataStorage = GetDataStorage(); - - if (dataStorage.IsNull()) - return; - vtkSmartPointer polyData = vtkSmartPointer::New(); vtkSmartPointer points = vtkSmartPointer::New(); const VecCoord& vertices = visualModelImpl->m_vertices2.getValue().empty() ? visualModelImpl->m_positions.getValue() : visualModelImpl->m_vertices2.getValue(); size_t numPoints = vertices.size(); points->SetNumberOfPoints(numPoints); for (size_t i = 0; i < numPoints; ++i) points->SetPoint(i, vertices[i].elems); polyData->SetPoints(points); vtkSmartPointer polys = vtkSmartPointer::New(); const ResizableExtVector& triangles = visualModelImpl->m_triangles.getValue(); if (!triangles.empty()) { ResizableExtVector::const_iterator trianglesEnd = triangles.end(); for (ResizableExtVector::const_iterator it = triangles.begin(); it != trianglesEnd; ++it) { const Triangle& triangle = *it; polys->InsertNextCell(3); polys->InsertCellPoint(triangle[0]); polys->InsertCellPoint(triangle[1]); polys->InsertCellPoint(triangle[2]); } } const ResizableExtVector& quads = visualModelImpl->m_quads.getValue(); if (!quads.empty()) { ResizableExtVector::const_iterator quadsEnd = quads.end(); for (ResizableExtVector::const_iterator it = quads.begin(); it != quadsEnd; ++it) { const Quad& quad = *it; polys->InsertNextCell(4); polys->InsertCellPoint(quad[0]); polys->InsertCellPoint(quad[1]); polys->InsertCellPoint(quad[2]); polys->InsertCellPoint(quad[3]); } } polyData->SetPolys(polys); const ResizableExtVector& normals = visualModelImpl->m_vnormals.getValue(); if (!normals.empty()) { size_t numNormals = normals.size(); vtkSmartPointer vtkNormals = vtkSmartPointer::New(); vtkNormals->SetNumberOfComponents(3); vtkNormals->SetNumberOfTuples(numNormals); for (size_t i = 0; i < numNormals; ++i) vtkNormals->SetTuple(i, normals[i].elems); polyData->GetPointData()->SetNormals(vtkNormals); } const VecTexCoord& texCoords = visualModelImpl->m_vtexcoords.getValue(); if (!texCoords.empty()) { size_t numTexCoords = texCoords.size(); vtkSmartPointer vtkTexCoords = vtkSmartPointer::New(); vtkTexCoords->SetNumberOfComponents(2); vtkTexCoords->SetNumberOfTuples(numTexCoords); for (size_t i = 0; i < numTexCoords; ++i) vtkTexCoords->SetTuple(i, texCoords[i].elems); polyData->GetPointData()->SetTCoords(vtkTexCoords); } Surface::Pointer surface = Surface::New(); surface->SetVtkPolyData(polyData); DataNode::Pointer dataNode = DataNode::New(); dataNode->SetName(visualModelImpl->name.getValue()); dataNode->SetData(surface); ApplyMaterial(dataNode, visualModelImpl->material.getValue()); - DataNode::Pointer parentDataNode = GetSimulationDataNode(node->getRoot()); + DataNode::Pointer parentDataNode = GetSimulationDataNode(m_DataStorage, node->getRoot()); if (parentDataNode.IsNotNull()) surface->SetGeometry(parentDataNode->GetData()->GetGeometry()); - dataStorage->Add(dataNode, parentDataNode); + m_DataStorage->Add(dataNode, parentDataNode); } diff --git a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h b/Modules/Simulation/mitkExportMitkVisitor.h similarity index 66% rename from Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h rename to Modules/Simulation/mitkExportMitkVisitor.h index 44729ba2ec..fb89e0ee35 100644 --- a/Plugins/org.mitk.simulation/src/mitkExportMitkVisitor.h +++ b/Modules/Simulation/mitkExportMitkVisitor.h @@ -1,44 +1,46 @@ /*=================================================================== 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 mitkExportMitkVisitor_h #define mitkExportMitkVisitor_h +#include #include -#include +#include namespace mitk { - class SIMULATION_INIT_EXPORT ExportMitkVisitor : public sofa::simulation::Visitor + class MitkSimulation_EXPORT ExportMitkVisitor : public sofa::simulation::Visitor { public: - explicit ExportMitkVisitor(const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); - explicit ExportMitkVisitor(const std::string& visualModelName, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); + explicit ExportMitkVisitor(DataStorage::Pointer dataStorage, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); + ExportMitkVisitor(DataStorage::Pointer dataStorage, const std::string& visualModelName, const sofa::core::ExecParams* params = sofa::core::ExecParams::defaultInstance()); ~ExportMitkVisitor(); Result processNodeTopDown(sofa::simulation::Node* node); private: ExportMitkVisitor(const ExportMitkVisitor&); ExportMitkVisitor& operator=(const ExportMitkVisitor&); void processVisualModel(sofa::simulation::Node* node, sofa::core::visual::VisualModel* visualModel); + DataStorage::Pointer m_DataStorage; std::string m_VisualModelName; }; } #endif diff --git a/Modules/Simulation/mitkISimulationService.h b/Modules/Simulation/mitkISimulationService.h index 4a077feb18..3406ce7827 100644 --- a/Modules/Simulation/mitkISimulationService.h +++ b/Modules/Simulation/mitkISimulationService.h @@ -1,44 +1,47 @@ /*=================================================================== 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 mitkISimulationService_h #define mitkISimulationService_h #include #include #include namespace mitk { + class Scheduler; + class MitkSimulation_EXPORT ISimulationService { public: - virtual Simulation::Pointer GetSimulation() const = 0; - virtual void SetSimulation(Simulation::Pointer simulation) = 0; + virtual Simulation::Pointer GetActiveSimulation() const = 0; + virtual void SetActiveSimulation(Simulation::Pointer activeSimulation) = 0; + virtual Scheduler* GetScheduler() = 0; protected: ISimulationService(); virtual ~ISimulationService(); private: ISimulationService(const ISimulationService&); ISimulationService& operator=(const ISimulationService&); }; } US_DECLARE_SERVICE_INTERFACE(mitk::ISimulationService, "org.mitk.ISimulationService"); #endif diff --git a/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp new file mode 100644 index 0000000000..e5adae66b6 --- /dev/null +++ b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.cpp @@ -0,0 +1,44 @@ +/*=================================================================== + +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 "mitkSchedulableProcess.h" +#include "mitkRoundRobinSchedulingAlgorithm.h" + +mitk::RoundRobinSchedulingAlgorithm::RoundRobinSchedulingAlgorithm() +{ +} + +mitk::RoundRobinSchedulingAlgorithm::~RoundRobinSchedulingAlgorithm() +{ +} + +mitk::SchedulableProcess* mitk::RoundRobinSchedulingAlgorithm::GetNextProcess(std::vector& processQueue) +{ + size_t numProcesses = processQueue.size(); + + if (numProcesses == 0) + return NULL; + + mitk::SchedulableProcess* process = processQueue[0]; + + if (numProcesses > 1) + { + processQueue.erase(processQueue.begin()); + processQueue.push_back(process); + } + + return process; +} diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h similarity index 60% copy from Modules/Simulation/mitkSimulationService.h copy to Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h index c8c3803fb8..4cf617d51f 100644 --- a/Modules/Simulation/mitkSimulationService.h +++ b/Modules/Simulation/mitkRoundRobinSchedulingAlgorithm.h @@ -1,38 +1,34 @@ /*=================================================================== 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 mitkSimulationService_h -#define mitkSimulationService_h +#ifndef mitkRoundRobinSchedulingAlgorithm_h +#define mitkRoundRobinSchedulingAlgorithm_h -#include +#include "mitkSchedulingAlgorithmBase.h" namespace mitk { - class SimulationService : public ISimulationService + class RoundRobinSchedulingAlgorithm : public SchedulingAlgorithmBase { public: - SimulationService(); - ~SimulationService(); + RoundRobinSchedulingAlgorithm(); + ~RoundRobinSchedulingAlgorithm(); - Simulation::Pointer GetSimulation() const; - void SetSimulation(Simulation::Pointer simulation); - - private: - Simulation::Pointer m_Simulation; + SchedulableProcess* GetNextProcess(std::vector& processQueue); }; } #endif diff --git a/Modules/Simulation/mitkSchedulableProcess.cpp b/Modules/Simulation/mitkSchedulableProcess.cpp new file mode 100644 index 0000000000..0849942deb --- /dev/null +++ b/Modules/Simulation/mitkSchedulableProcess.cpp @@ -0,0 +1,53 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkSchedulableProcess.h" +#include + +mitk::SchedulableProcess::SchedulableProcess(int priority) + : m_Priority(priority) +{ +} + +mitk::SchedulableProcess::~SchedulableProcess() +{ +} + +int mitk::SchedulableProcess::GetPriority() const +{ + return m_Priority; +} + +boost::chrono::nanoseconds mitk::SchedulableProcess::GetTotalElapsedTime() const +{ + return m_TotalElapsedTime; +} + +void mitk::SchedulableProcess::ResetTotalElapsedTime(boost::chrono::nanoseconds carryover) +{ + m_TotalElapsedTime = carryover; +} + +boost::chrono::nanoseconds mitk::SchedulableProcess::GetElapsedTime() const +{ + return m_ElapsedTime; +} + +void mitk::SchedulableProcess::SetElapsedTime(boost::chrono::nanoseconds elapsedTime) +{ + m_TotalElapsedTime += elapsedTime; + m_ElapsedTime = elapsedTime; +} diff --git a/Modules/Simulation/mitkSchedulableProcess.h b/Modules/Simulation/mitkSchedulableProcess.h new file mode 100644 index 0000000000..4c26c26022 --- /dev/null +++ b/Modules/Simulation/mitkSchedulableProcess.h @@ -0,0 +1,49 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkSchedulableProcess_h +#define mitkSchedulableProcess_h + +#include +#include + +namespace mitk +{ + class MitkSimulation_EXPORT SchedulableProcess + { + public: + explicit SchedulableProcess(int priority = 0); + virtual ~SchedulableProcess(); + + int GetPriority() const; + boost::chrono::nanoseconds GetTotalElapsedTime() const; + void ResetTotalElapsedTime(boost::chrono::nanoseconds carryover = boost::chrono::nanoseconds::zero()); + boost::chrono::nanoseconds GetElapsedTime() const; + + protected: + void SetElapsedTime(boost::chrono::nanoseconds elapsedTime); + + private: + SchedulableProcess(const SchedulableProcess&); + SchedulableProcess& operator=(const SchedulableProcess&); + + int m_Priority; + boost::chrono::nanoseconds m_TotalElapsedTime; + boost::chrono::nanoseconds m_ElapsedTime; + }; +} + +#endif diff --git a/Modules/Simulation/mitkScheduler.cpp b/Modules/Simulation/mitkScheduler.cpp new file mode 100644 index 0000000000..bad6487f6a --- /dev/null +++ b/Modules/Simulation/mitkScheduler.cpp @@ -0,0 +1,90 @@ +/*=================================================================== + +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 "mitkRoundRobinSchedulingAlgorithm.h" +#include "mitkSchedulableProcess.h" +#include "mitkScheduler.h" +#include "mitkWeightedRoundRobinSchedulingAlgorithm.h" +#include +#include +#include + +struct mitk::Scheduler::Impl +{ + std::vector processQueue; + SchedulingAlgorithmBase* algorithm; +}; + +mitk::Scheduler::Scheduler(SchedulingAlgorithm::Enum algorithm) + : m_Impl(new Impl) +{ + switch (algorithm) + { + case mitk::SchedulingAlgorithm::RoundRobin: + m_Impl->algorithm = new mitk::RoundRobinSchedulingAlgorithm; + break; + + case mitk::SchedulingAlgorithm::WeightedRoundRobin: + m_Impl->algorithm = new mitk::WeightedRoundRobinSchedulingAlgorithm; + break; + + default: + assert(false && "Unknown scheduling algorithm!"); + } +} + +mitk::Scheduler::~Scheduler() +{ + delete m_Impl->algorithm; + delete m_Impl; +} + +void mitk::Scheduler::AddProcess(SchedulableProcess* process) +{ + if (process == NULL) + return; + + if (std::find(m_Impl->processQueue.begin(), m_Impl->processQueue.end(), process) == m_Impl->processQueue.end()) + m_Impl->processQueue.push_back(process); +} + +void mitk::Scheduler::RemoveProcess(SchedulableProcess* process) +{ + if (process == NULL) + return; + + std::vector::iterator it = std::find(m_Impl->processQueue.begin(), m_Impl->processQueue.end(), process); + + if (it != m_Impl->processQueue.end()) + m_Impl->processQueue.erase(it); +} + +bool mitk::Scheduler::IsEmpty() const +{ + return m_Impl->processQueue.empty(); +} + +mitk::SchedulableProcess* mitk::Scheduler::GetCurrentProcess() +{ + return !m_Impl->processQueue.empty() + ? m_Impl->processQueue[0] + : NULL; +} + +mitk::SchedulableProcess* mitk::Scheduler::GetNextProcess() +{ + return m_Impl->algorithm->GetNextProcess(m_Impl->processQueue); +} diff --git a/Modules/Simulation/mitkScheduler.h b/Modules/Simulation/mitkScheduler.h new file mode 100644 index 0000000000..da68a33848 --- /dev/null +++ b/Modules/Simulation/mitkScheduler.h @@ -0,0 +1,57 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkScheduler_h +#define mitkScheduler_h + +#include + +namespace mitk +{ + class SchedulableProcess; + class SchedulingAlgorithmBase; + + namespace SchedulingAlgorithm + { + enum Enum + { + RoundRobin, + WeightedRoundRobin + }; + } + + class MitkSimulation_EXPORT Scheduler + { + public: + explicit Scheduler(SchedulingAlgorithm::Enum algorithm = SchedulingAlgorithm::RoundRobin); + ~Scheduler(); + + void AddProcess(SchedulableProcess* process); + void RemoveProcess(SchedulableProcess* process); + bool IsEmpty() const; + SchedulableProcess* GetCurrentProcess(); + SchedulableProcess* GetNextProcess(); + + private: + Scheduler(const Scheduler&); + Scheduler& operator=(const Scheduler&); + + struct Impl; + Impl* m_Impl; + }; +} + +#endif diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h b/Modules/Simulation/mitkSchedulingAlgorithmBase.cpp similarity index 72% copy from Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h copy to Modules/Simulation/mitkSchedulingAlgorithmBase.cpp index f99fdb6099..0a1586c71a 100644 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h +++ b/Modules/Simulation/mitkSchedulingAlgorithmBase.cpp @@ -1,27 +1,26 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef mitkGetDataStorage_h -#define mitkGetDataStorage_h +#include "mitkSchedulableProcess.h" +#include "mitkSchedulingAlgorithmBase.h" -#include - -namespace mitk +mitk::SchedulingAlgorithmBase::SchedulingAlgorithmBase() { - DataStorage::Pointer GetDataStorage(); } -#endif +mitk::SchedulingAlgorithmBase::~SchedulingAlgorithmBase() +{ +} diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSchedulingAlgorithmBase.h similarity index 55% copy from Modules/Simulation/mitkSimulationService.h copy to Modules/Simulation/mitkSchedulingAlgorithmBase.h index c8c3803fb8..3f39462171 100644 --- a/Modules/Simulation/mitkSimulationService.h +++ b/Modules/Simulation/mitkSchedulingAlgorithmBase.h @@ -1,38 +1,40 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef mitkSimulationService_h -#define mitkSimulationService_h +#ifndef mitkSchedulingAlgorithmBase_h +#define mitkSchedulingAlgorithmBase_h -#include +#include namespace mitk { - class SimulationService : public ISimulationService + class SchedulableProcess; + + class SchedulingAlgorithmBase { public: - SimulationService(); - ~SimulationService(); + SchedulingAlgorithmBase(); + virtual ~SchedulingAlgorithmBase(); - Simulation::Pointer GetSimulation() const; - void SetSimulation(Simulation::Pointer simulation); + virtual SchedulableProcess* GetNextProcess(std::vector& processQueue) = 0; private: - Simulation::Pointer m_Simulation; + SchedulingAlgorithmBase(const SchedulingAlgorithmBase&); + SchedulingAlgorithmBase& operator=(const SchedulingAlgorithmBase&); }; } #endif diff --git a/Modules/Simulation/mitkSimulation.cpp b/Modules/Simulation/mitkSimulation.cpp index 68dfa9cf54..99f7518c1c 100644 --- a/Modules/Simulation/mitkSimulation.cpp +++ b/Modules/Simulation/mitkSimulation.cpp @@ -1,158 +1,169 @@ /*=================================================================== 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 "mitkSimulation.h" #include #include "mitkGeometry3D.h" static sofa::simulation::Simulation::SPtr CreateSimulation() { const std::string key = "MultiMappingObject"; if (sofa::simulation::xml::BaseElement::NodeFactory::HasKey(key)) sofa::simulation::xml::BaseElement::NodeFactory::ResetEntry(key); return sofa::core::objectmodel::New(); } mitk::Simulation::Simulation() - : m_Simulation(CreateSimulation()) + : m_SOFASimulation(CreateSimulation()) { } mitk::Simulation::~Simulation() { if (m_RootNode) { - if (m_Simulation) - m_Simulation->unload(m_RootNode); + if (m_SOFASimulation) + m_SOFASimulation->unload(m_RootNode); } } void mitk::Simulation::Animate() { - if (!m_RootNode || !m_Simulation) + if (!m_RootNode || !m_SOFASimulation) return; - m_Simulation->animate(m_RootNode.get(), m_RootNode->getDt()); + boost::chrono::high_resolution_clock::time_point t0 = boost::chrono::high_resolution_clock::now(); + m_SOFASimulation->animate(m_RootNode.get(), m_RootNode->getDt()); + this->SetElapsedTime(boost::chrono::high_resolution_clock::now() - t0); + + this->UpdateOutputInformation(); } sofa::core::visual::DrawTool* mitk::Simulation::GetDrawTool() { return &m_DrawTool; } sofa::simulation::Node::SPtr mitk::Simulation::GetRootNode() const { return m_RootNode; } -sofa::simulation::Simulation::SPtr mitk::Simulation::GetSimulation() const +sofa::simulation::Simulation::SPtr mitk::Simulation::GetSOFASimulation() const { - return m_Simulation; + return m_SOFASimulation; } void mitk::Simulation::Reset() { - if (!m_RootNode || !m_Simulation) + if (!m_RootNode || !m_SOFASimulation) return; - m_Simulation->reset(m_RootNode.get()); + m_SOFASimulation->reset(m_RootNode.get()); m_RootNode->setTime(0.0); - m_Simulation->updateContext(m_RootNode.get()); + m_SOFASimulation->updateContext(m_RootNode.get()); +} + +bool mitk::Simulation::GetAnimationFlag() const +{ + return m_RootNode + ? m_RootNode->getContext()->getAnimate() + : false; } void mitk::Simulation::SetAnimationFlag(bool animate) { if (m_RootNode) m_RootNode->getContext()->setAnimate(animate); } void mitk::Simulation::SetDt(double dt) { if (m_RootNode) m_RootNode->setDt(dt); } void mitk::Simulation::SetRootNode(sofa::simulation::Node::SPtr rootNode) { m_RootNode = rootNode; } bool mitk::Simulation::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } void mitk::Simulation::SetRequestedRegion(const itk::DataObject*) { } void mitk::Simulation::SetRequestedRegionToLargestPossibleRegion() { } void mitk::Simulation::UpdateOutputInformation() { using sofa::defaulttype::BoundingBox; using sofa::defaulttype::Vector3; if (this->GetSource().IsNotNull()) this->GetSource()->UpdateOutputInformation(); if (m_RootNode) { const BoundingBox& boundingBox = m_RootNode->f_bbox.getValue(); mitk::Geometry3D::BoundsArrayType bounds; if (boundingBox.isValid()) { const Vector3& min = boundingBox.minBBox(); const Vector3& max = boundingBox.maxBBox(); bounds[0] = static_cast(min.x()); bounds[1] = static_cast(max.x()); bounds[2] = static_cast(min.y()); bounds[3] = static_cast(max.y()); bounds[4] = static_cast(min.z()); bounds[5] = static_cast(max.z()); } else { bounds.Fill(0.0f); } mitk::BaseGeometry::Pointer geometry = this->GetGeometry(); if (geometry.IsNull()) { geometry = Geometry3D::New(); geometry->SetBounds(bounds); this->SetGeometry(geometry); } else { geometry->SetBounds(bounds); } } this->GetTimeGeometry()->Update(); } bool mitk::Simulation::VerifyRequestedRegion() { return true; } diff --git a/Modules/Simulation/mitkSimulation.h b/Modules/Simulation/mitkSimulation.h index f9618de21d..de440818c4 100644 --- a/Modules/Simulation/mitkSimulation.h +++ b/Modules/Simulation/mitkSimulation.h @@ -1,59 +1,61 @@ /*=================================================================== 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 mitkSimulation_h #define mitkSimulation_h #include +#include #include #include #include namespace mitk { - class MitkSimulation_EXPORT Simulation : public BaseData + class MitkSimulation_EXPORT Simulation : public BaseData, public SchedulableProcess { public: mitkClassMacro(Simulation, BaseData); itkFactorylessNewMacro(Self) itkCloneMacro(Self) void Animate(); sofa::core::visual::DrawTool* GetDrawTool(); sofa::simulation::Node::SPtr GetRootNode() const; - sofa::simulation::Simulation::SPtr GetSimulation() const; + sofa::simulation::Simulation::SPtr GetSOFASimulation() const; void Reset(); + bool GetAnimationFlag() const; void SetAnimationFlag(bool animate); void SetDt(double dt); void SetRootNode(sofa::simulation::Node::SPtr rootNode); bool RequestedRegionIsOutsideOfTheBufferedRegion(); void SetRequestedRegion(const itk::DataObject*); void SetRequestedRegionToLargestPossibleRegion(); void UpdateOutputInformation(); bool VerifyRequestedRegion(); private: Simulation(); ~Simulation(); - sofa::simulation::Simulation::SPtr m_Simulation; + sofa::simulation::Simulation::SPtr m_SOFASimulation; sofa::simulation::Node::SPtr m_RootNode; sofa::core::visual::DrawToolGL m_DrawTool; }; } #endif diff --git a/Modules/Simulation/mitkSimulationInteractor.cpp b/Modules/Simulation/mitkSimulationInteractor.cpp new file mode 100644 index 0000000000..1b989d4f0c --- /dev/null +++ b/Modules/Simulation/mitkSimulationInteractor.cpp @@ -0,0 +1,526 @@ +/*=================================================================== + +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 "mitkSimulation.h" +#include "mitkSimulationInteractor.h" + +using sofa::component::collision::AttachBodyPerformer; +using sofa::component::collision::BaseRayContact; +using sofa::component::collision::BodyPicked; +using sofa::component::collision::ComponentMouseInteraction; +using sofa::component::collision::FixParticlePerformerConfiguration; +using sofa::component::collision::InteractionPerformer; +using sofa::component::collision::Ray; +using sofa::component::collision::RayModel; +using sofa::component::container::MechanicalObject; +using sofa::core::behavior::BaseMechanicalState; +using sofa::core::collision::DetectionOutput; +using sofa::core::collision::Pipeline; +using sofa::core::objectmodel::BaseContext; +using sofa::core::CollisionElementIterator; +using sofa::core::ExecParams; +using sofa::core::MechanicalParams; +using sofa::core::VecCoordId; +using sofa::defaulttype::dot; +using sofa::defaulttype::Vec3d; +using sofa::defaulttype::Vec3Types; +using sofa::helper::vector; +using sofa::simulation::CollisionVisitor; +using sofa::simulation::DeleteVisitor; +using sofa::simulation::MechanicalPickParticlesVisitor; +using sofa::simulation::MechanicalPropagatePositionVisitor; +using sofa::simulation::Node; + +namespace mitk +{ + class SimulationInteractor::Impl + { + public: + Impl(); + ~Impl(); + + void Initialize(Node::SPtr rootNode); + void Uninitialize(); + void AttachMouseNode(); + void DetachMouseNode(); + bool IsInteractionPerformerNotNull() const; + void UpdatePickRay(InteractionPositionEvent* event); + void FindCollision(); + void AttachCompatibleInteraction(); + void DetachInteraction(bool setNull); + void StartInteraction(const std::string& type); + void ExecuteInteraction(); + void StopInteraction(); + + private: + Impl(const Impl&); + Impl& operator=(const Impl&); + + BodyPicked FindCollisionUsingPipeline(); + BodyPicked FindCollisionUsingBruteForce(); + void ConfigureInteractionPerformer(); + + Node::SPtr m_RootNode; + Node::SPtr m_MouseNode; + MechanicalObject::SPtr m_PickRayContainer; + RayModel::SPtr m_PickRayModel; + std::vector m_InteractionComponents; + ComponentMouseInteraction* m_Interaction; + std::auto_ptr m_InteractionPerformer; + bool m_IsMouseNodeAttached; + bool m_UseCollisionPipeline; + BodyPicked m_LastBodyPicked; + }; +} + +mitk::SimulationInteractor::Impl::Impl() + : m_Interaction(NULL), + m_IsMouseNodeAttached(false), + m_UseCollisionPipeline(true) +{ +} + +mitk::SimulationInteractor::Impl::~Impl() +{ + this->Uninitialize(); +} + +void mitk::SimulationInteractor::Impl::Initialize(const Node::SPtr rootNode) +{ + this->Uninitialize(); + + m_RootNode = rootNode; + + m_PickRayContainer = sofa::core::objectmodel::New >(); + m_PickRayContainer->setName("MousePosition"); + m_PickRayContainer->resize(1); + + m_PickRayModel = sofa::core::objectmodel::New(); + m_PickRayModel->setName("MouseCollisionModel"); + m_PickRayModel->setNbRay(1); + + m_MouseNode = rootNode->createChild("Mouse"); + m_MouseNode->addObject(m_PickRayContainer); + m_MouseNode->addObject(m_PickRayModel); + + m_MouseNode->init(ExecParams::defaultInstance()); + m_PickRayContainer->init(); + m_PickRayModel->init(); + + typedef ComponentMouseInteraction::ComponentMouseInteractionFactory Factory; + const Factory* factory = Factory::getInstance(); + + for (Factory::const_iterator it = factory->begin(); it != factory->end(); ++it) + m_InteractionComponents.push_back(it->second->createInstance(NULL)); + + m_MouseNode->detachFromGraph(); + + Pipeline* collisionPipeline; + rootNode->getContext()->get(collisionPipeline, BaseContext::SearchRoot); + + m_UseCollisionPipeline = collisionPipeline != NULL; +} + +void mitk::SimulationInteractor::Impl::Uninitialize() +{ + this->DetachMouseNode(); + + if (!m_InteractionComponents.empty()) + { + for (std::vector::iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it) + delete *it; + + m_InteractionComponents.clear(); + m_Interaction = NULL; + } + + if (m_MouseNode) + { + m_MouseNode->execute(ExecParams::defaultInstance()); + + m_PickRayModel.reset(); + m_PickRayContainer.reset(); + m_MouseNode.reset(); + m_RootNode.reset(); + } +} + +void mitk::SimulationInteractor::Impl::AttachMouseNode() +{ + if (!m_IsMouseNodeAttached) + { + m_RootNode->addChild(m_MouseNode); + m_IsMouseNodeAttached = true; + } +} + +void mitk::SimulationInteractor::Impl::DetachMouseNode() +{ + if (m_IsMouseNodeAttached) + { + this->DetachInteraction(false); + m_MouseNode->detachFromGraph(); + m_IsMouseNodeAttached = false; + } +} + +bool mitk::SimulationInteractor::Impl::IsInteractionPerformerNotNull() const +{ + return m_InteractionPerformer.get() != NULL; +} + +void mitk::SimulationInteractor::Impl::UpdatePickRay(InteractionPositionEvent* event) +{ + if (!m_IsMouseNodeAttached) + return; + + vtkCamera* camera = event->GetSender()->GetVtkRenderer()->GetActiveCamera(); + + Vec3d cameraOrigin(camera->GetPosition()); + Vec3d pickedPosition(event->GetPositionInWorld().GetDataPointer()); + Vec3d pickRayDirection(pickedPosition - cameraOrigin); + Vec3d focalPoint(camera->GetFocalPoint()); + + Vec3d cameraDirection(focalPoint - cameraOrigin); + cameraDirection.normalize(); + + std::pair clippingRange; + camera->GetClippingRange(clippingRange.first, clippingRange.second); + + double dotProduct = dot(cameraDirection, pickRayDirection); + double norm = pickRayDirection.norm(); + + clippingRange.first = clippingRange.first / dotProduct * norm; + clippingRange.second = clippingRange.second / dotProduct * norm; + + pickRayDirection.normalize(); + + Ray pickRay = m_PickRayModel->getRay(0); + pickRay.setOrigin(cameraOrigin + pickRayDirection * clippingRange.first); + pickRay.setDirection(pickRayDirection); + pickRay.setL(clippingRange.second - clippingRange.first); + + MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::position(), true) + .execute(m_PickRayModel->getContext()); + + MechanicalPropagatePositionVisitor(MechanicalParams::defaultInstance(), 0, VecCoordId::freePosition(), true) + .execute(m_PickRayModel->getContext()); +} + +void mitk::SimulationInteractor::Impl::FindCollision() +{ + CollisionVisitor(ExecParams::defaultInstance()).execute(m_RootNode->getContext()); + + if (m_UseCollisionPipeline) + { + m_LastBodyPicked = this->FindCollisionUsingPipeline(); + + if (m_LastBodyPicked.body != NULL) + return; + } + + m_LastBodyPicked = this->FindCollisionUsingBruteForce(); +} + +BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingPipeline() +{ + BodyPicked bodyPicked; + + Ray ray = m_PickRayModel->getRay(0); + const Vec3d& origin = ray.origin(); + const Vec3d& direction = ray.direction(); + const double length = ray.l(); + + const std::set& contacts = m_PickRayModel->getContacts(); + + for (std::set::const_iterator contact = contacts.begin(); contact != contacts.end(); ++contact) + { + const vector& detectionOutputs = (*contact)->getDetectionOutputs(); + + for (vector::const_iterator detectionOutput = detectionOutputs.begin(); detectionOutput != detectionOutputs.end(); ++detectionOutput) + { + CollisionElementIterator collisionElement; + int pointIndex; + + if ((*detectionOutput)->elem.first.getCollisionModel() == m_PickRayModel) + { + collisionElement = (*detectionOutput)->elem.second; + pointIndex = 1; + } + else if ((*detectionOutput)->elem.second.getCollisionModel() == m_PickRayModel) + { + collisionElement = (*detectionOutput)->elem.first; + pointIndex = 0; + } + else + { + continue; + } + + if (!collisionElement.getCollisionModel()->isSimulated()) + continue; + + const double t = ((*detectionOutput)->point[pointIndex] - origin) * direction; + + if (t < 0.0 || t > length) + continue; + + if (bodyPicked.body == NULL || t < bodyPicked.rayLength) + { + bodyPicked.body = collisionElement.getCollisionModel(); + bodyPicked.indexCollisionElement = collisionElement.getIndex(); + bodyPicked.point = (*detectionOutput)->point[pointIndex]; + bodyPicked.dist = ((*detectionOutput)->point[1] - (*detectionOutput)->point[0]).norm(); + bodyPicked.rayLength = t; + } + } + } + + return bodyPicked; +} + +BodyPicked mitk::SimulationInteractor::Impl::FindCollisionUsingBruteForce() +{ + BodyPicked bodyPicked; + + Ray ray = m_PickRayModel->getRay(0); + const Vec3d& origin = ray.origin(); + const Vec3d& direction = ray.direction(); + const double length = ray.l(); + + MechanicalPickParticlesVisitor pickVisitor(ExecParams::defaultInstance(), origin, direction, length); + pickVisitor.execute(m_RootNode->getContext()); + + if (!pickVisitor.particles.empty()) + { + bodyPicked.mstate = pickVisitor.particles.begin()->second.first; + bodyPicked.indexCollisionElement = pickVisitor.particles.begin()->second.second; + bodyPicked.point[0] = bodyPicked.mstate->getPX(bodyPicked.indexCollisionElement); + bodyPicked.point[1] = bodyPicked.mstate->getPY(bodyPicked.indexCollisionElement); + bodyPicked.point[2] = bodyPicked.mstate->getPZ(bodyPicked.indexCollisionElement); + bodyPicked.dist = 0; + bodyPicked.rayLength = (bodyPicked.point - origin) * direction; + } + + return bodyPicked; +} + +void mitk::SimulationInteractor::Impl::AttachCompatibleInteraction() +{ + BaseContext* context; + + if (m_LastBodyPicked.body == NULL) + { + context = m_LastBodyPicked.mstate != NULL + ? m_LastBodyPicked.mstate->getContext() + : NULL; + } + else + { + context = m_LastBodyPicked.body->getContext(); + } + + if (context != NULL) + { + if (m_Interaction == NULL || !m_Interaction->isCompatible(context)) + { + bool foundCompatibleInteractor = false; + + for (std::vector::const_iterator it = m_InteractionComponents.begin(); it != m_InteractionComponents.end(); ++it) + { + if (*it != m_Interaction && (*it)->isCompatible(context)) + { + this->DetachInteraction(false); + m_Interaction = *it; + m_Interaction->attach(m_MouseNode.get()); + + foundCompatibleInteractor = true; + break; + } + } + + if (!foundCompatibleInteractor) + this->DetachInteraction(true); + } + } + else + { + this->DetachInteraction(true); + } + + if (m_Interaction != NULL) + { + m_Interaction->mouseInteractor->setMouseRayModel(m_PickRayModel.get()); + m_Interaction->mouseInteractor->setBodyPicked(m_LastBodyPicked); + } +} + +void mitk::SimulationInteractor::Impl::DetachInteraction(bool setNull) +{ + if (m_Interaction != NULL) + { + m_Interaction->detach(); + + if (setNull) + m_Interaction = NULL; + } +} + +void mitk::SimulationInteractor::Impl::StartInteraction(const std::string& type) +{ + if (m_Interaction == NULL) + return; + + InteractionPerformer::InteractionPerformerFactory* factory = InteractionPerformer::InteractionPerformerFactory::getInstance(); + m_InteractionPerformer.reset(factory->createObject(type, m_Interaction->mouseInteractor.get())); + + if (m_InteractionPerformer.get() != NULL) + { + this->ConfigureInteractionPerformer(); + m_Interaction->mouseInteractor->addInteractionPerformer(m_InteractionPerformer.get()); + m_InteractionPerformer->start(); + } +} + +void mitk::SimulationInteractor::Impl::ConfigureInteractionPerformer() +{ + AttachBodyPerformer* attachBodyPerformer = dynamic_cast*>(m_InteractionPerformer.get()); + + if (attachBodyPerformer != NULL) + { + attachBodyPerformer->setStiffness(1000); + attachBodyPerformer->setArrowSize(0); + attachBodyPerformer->setShowFactorSize(1); + return; + } + + FixParticlePerformerConfiguration* fixParticlePerformer = dynamic_cast(m_InteractionPerformer.get()); + + if (fixParticlePerformer != NULL) + fixParticlePerformer->setStiffness(10000); +} + +void mitk::SimulationInteractor::Impl::ExecuteInteraction() +{ + if (m_InteractionPerformer.get() == NULL) + return; + + m_InteractionPerformer->execute(); +} + +void mitk::SimulationInteractor::Impl::StopInteraction() +{ + if (m_InteractionPerformer.get() == NULL) + return; + + AttachBodyPerformer* attachBodyPerformer = dynamic_cast*>(m_InteractionPerformer.get()); + + if (attachBodyPerformer != NULL) + attachBodyPerformer->clear(); + + m_Interaction->mouseInteractor->removeInteractionPerformer(m_InteractionPerformer.get()); + m_InteractionPerformer.release(); +} + +mitk::SimulationInteractor::SimulationInteractor() + : m_Impl(new Impl) +{ +} + +mitk::SimulationInteractor::~SimulationInteractor() +{ +} + +void mitk::SimulationInteractor::ConnectActionsAndFunctions() +{ + CONNECT_FUNCTION("startPrimaryInteraction", StartPrimaryInteraction); + CONNECT_FUNCTION("startSecondaryInteraction", StartSecondaryInteraction); + CONNECT_FUNCTION("stopInteraction", StopInteraction); + CONNECT_FUNCTION("executeInteraction", ExecuteInteraction); + CONNECT_CONDITION("isInteractionPerformerNotNull", IsInteractionPerformerNotNull); +} + +void mitk::SimulationInteractor::DataNodeChanged() +{ + this->ResetToStartState(); + + NodeType dataNode = this->GetDataNode(); + + if (dataNode.IsNotNull()) + { + Simulation::Pointer simulation = dynamic_cast(dataNode->GetData()); + + if (simulation.IsNotNull()) + { + m_Impl->Initialize(simulation->GetRootNode()); + return; + } + } + + m_Impl->Uninitialize(); +} + +void mitk::SimulationInteractor::StartInteraction(const std::string& type, InteractionPositionEvent* event) +{ + m_Impl->AttachMouseNode(); + m_Impl->UpdatePickRay(event); + m_Impl->FindCollision(); + m_Impl->AttachCompatibleInteraction(); + m_Impl->StartInteraction(type); +} + +bool mitk::SimulationInteractor::StartPrimaryInteraction(StateMachineAction*, InteractionEvent* event) +{ + this->StartInteraction("AttachBody", dynamic_cast(event)); + return true; +} + +bool mitk::SimulationInteractor::StartSecondaryInteraction(StateMachineAction*, InteractionEvent* event) +{ + this->StartInteraction("FixParticle", dynamic_cast(event)); + return true; +} + +bool mitk::SimulationInteractor::StopInteraction(StateMachineAction*, InteractionEvent*) +{ + m_Impl->StopInteraction(); + m_Impl->DetachMouseNode(); + return true; +} + +bool mitk::SimulationInteractor::ExecuteInteraction(StateMachineAction*, InteractionEvent* event) +{ + m_Impl->UpdatePickRay(dynamic_cast(event)); + m_Impl->ExecuteInteraction(); + return true; +} + +bool mitk::SimulationInteractor::IsInteractionPerformerNotNull(const InteractionEvent*) +{ + return m_Impl->IsInteractionPerformerNotNull(); +} diff --git a/Modules/Simulation/mitkSimulationInteractor.h b/Modules/Simulation/mitkSimulationInteractor.h new file mode 100644 index 0000000000..6e838d86f7 --- /dev/null +++ b/Modules/Simulation/mitkSimulationInteractor.h @@ -0,0 +1,54 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkSimulationInteractor_h +#define mitkSimulationInteractor_h + +#include +#include + +namespace mitk +{ + class InteractionPositionEvent; + + class MitkSimulation_EXPORT SimulationInteractor : public DataInteractor + { + public: + mitkClassMacro(SimulationInteractor, DataInteractor); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + protected: + void ConnectActionsAndFunctions(); + void DataNodeChanged(); + + private: + SimulationInteractor(); + ~SimulationInteractor(); + + void StartInteraction(const std::string& type, InteractionPositionEvent* event); + bool StartPrimaryInteraction(StateMachineAction* action, InteractionEvent* event); + bool StartSecondaryInteraction(StateMachineAction* action, InteractionEvent* event); + bool ExecuteInteraction(StateMachineAction* action, InteractionEvent* event); + bool StopInteraction(StateMachineAction* action, InteractionEvent* event); + bool IsInteractionPerformerNotNull(const InteractionEvent* event); + + class Impl; + std::auto_ptr m_Impl; + }; +} + +#endif diff --git a/Modules/Simulation/mitkSimulationObjectFactory.cpp b/Modules/Simulation/mitkSimulationObjectFactory.cpp index f1bbee1116..320009f7bc 100644 --- a/Modules/Simulation/mitkSimulationObjectFactory.cpp +++ b/Modules/Simulation/mitkSimulationObjectFactory.cpp @@ -1,135 +1,143 @@ /*=================================================================== 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 "mitkIndexROI.h" #include "mitkSimulation.h" #include "mitkSimulationObjectFactory.h" #include "mitkSimulationVtkMapper3D.h" +#include "mitkSimulationWriter.h" #include "mitkVtkModel.h" #include #include #include #include +#include #include static void InitializeSofa() { int argc = 0; glutInit(&argc, NULL); sofa::component::init(); sofa::simulation::xml::initXml(); + + sofa::core::visual::VisualParams::defaultInstance()->setSupported(sofa::core::visual::API_OpenGL); } static void RegisterSofaClasses() { using sofa::core::ObjectFactory; using sofa::core::RegisterObject; int IndexROIClass = RegisterObject("").add(); int VtkModelClass = RegisterObject("").add(); ObjectFactory::AddAlias("VisualModel", "VtkModel", true); ObjectFactory::AddAlias("OglModel", "VtkModel", true); } mitk::SimulationObjectFactory::SimulationObjectFactory() - : m_SimulationIOFactory(SimulationIOFactory::New()) + : m_SimulationIOFactory(SimulationIOFactory::New()), + m_SimulationWriterFactory(SimulationWriterFactory::New()) { itk::ObjectFactoryBase::RegisterFactory(m_SimulationIOFactory); + itk::ObjectFactoryBase::RegisterFactory(m_SimulationWriterFactory); + + m_FileWriters.push_back(SimulationWriter::New().GetPointer()); std::string description = "SOFA Scene Files"; m_FileExtensionsMap.insert(std::pair("*.scn", description)); - m_FileExtensionsMap.insert(std::pair("*.xml", description)); InitializeSofa(); RegisterSofaClasses(); } mitk::SimulationObjectFactory::~SimulationObjectFactory() { + itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationWriterFactory); itk::ObjectFactoryBase::UnRegisterFactory(m_SimulationIOFactory); } mitk::Mapper::Pointer mitk::SimulationObjectFactory::CreateMapper(mitk::DataNode* node, MapperSlotId slotId) { Mapper::Pointer mapper; if (dynamic_cast(node->GetData()) != NULL) { if (slotId == BaseRenderer::Standard3D) mapper = mitk::SimulationVtkMapper3D::New(); if (mapper.IsNotNull()) mapper->SetDataNode(node); } return mapper; } const char* mitk::SimulationObjectFactory::GetDescription() const { return "Simulation Object Factory"; } const char* mitk::SimulationObjectFactory::GetFileExtensions() { std::string fileExtensions; this->CreateFileExtensions(m_FileExtensionsMap, fileExtensions); return fileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetFileExtensionsMap() { return m_FileExtensionsMap; } const char* mitk::SimulationObjectFactory::GetITKSourceVersion() const { return ITK_SOURCE_VERSION; } const char* mitk::SimulationObjectFactory::GetSaveFileExtensions() { std::string saveFileExtensions; this->CreateFileExtensions(m_FileExtensionsMap, saveFileExtensions); return saveFileExtensions.c_str(); } mitk::CoreObjectFactoryBase::MultimapType mitk::SimulationObjectFactory::GetSaveFileExtensionsMap() { return m_SaveFileExtensionsMap; } void mitk::SimulationObjectFactory::SetDefaultProperties(mitk::DataNode* node) { if (node == NULL) return; if (dynamic_cast(node->GetData()) != NULL) SimulationVtkMapper3D::SetDefaultProperties(node); } void mitk::RegisterSimulationObjectFactory() { static bool alreadyRegistered = false; if (!alreadyRegistered) { mitk::CoreObjectFactory::GetInstance()->RegisterExtraFactory(mitk::SimulationObjectFactory::New()); alreadyRegistered = true; } } diff --git a/Modules/Simulation/mitkSimulationObjectFactory.h b/Modules/Simulation/mitkSimulationObjectFactory.h index c27cb57a43..49d4f23752 100644 --- a/Modules/Simulation/mitkSimulationObjectFactory.h +++ b/Modules/Simulation/mitkSimulationObjectFactory.h @@ -1,52 +1,54 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkSimulationObjectFactory_h #define mitkSimulationObjectFactory_h #include "mitkSimulationIOFactory.h" +#include "mitkSimulationWriterFactory.h" #include namespace mitk { class MitkSimulation_EXPORT SimulationObjectFactory : public CoreObjectFactoryBase { public: mitkClassMacro(SimulationObjectFactory, CoreObjectFactoryBase); itkFactorylessNewMacro(Self); Mapper::Pointer CreateMapper(DataNode* node, MapperSlotId slotId); const char* GetDescription() const; const char* GetFileExtensions(); MultimapType GetFileExtensionsMap(); const char* GetITKSourceVersion() const; const char* GetSaveFileExtensions(); MultimapType GetSaveFileExtensionsMap(); void SetDefaultProperties(DataNode* node); private: SimulationObjectFactory(); ~SimulationObjectFactory(); SimulationIOFactory::Pointer m_SimulationIOFactory; + SimulationWriterFactory::Pointer m_SimulationWriterFactory; MultimapType m_FileExtensionsMap; MultimapType m_SaveFileExtensionsMap; }; MitkSimulation_EXPORT void RegisterSimulationObjectFactory(); } #endif diff --git a/Modules/Simulation/mitkSimulationReader.cpp b/Modules/Simulation/mitkSimulationReader.cpp index 4b035bafef..2738134cdd 100644 --- a/Modules/Simulation/mitkSimulationReader.cpp +++ b/Modules/Simulation/mitkSimulationReader.cpp @@ -1,128 +1,159 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGetSimulationService.h" #include "mitkISimulationService.h" #include "mitkSimulation.h" #include "mitkSimulationReader.h" +#include #include #include bool mitk::SimulationReader::CanReadFile(const std::string& filename, const std::string&, const std::string&) { std::string::size_type length = filename.length(); if (length < 5) return false; std::string ext = filename.substr(length - 4); std::transform(ext.begin(), ext.end(), ext.begin(), tolower); if (ext == ".scn" || ext == ".xml") return true; return false; } mitk::SimulationReader::SimulationReader() { mitk::Simulation::Pointer output = mitk::Simulation::New(); this->SetNumberOfRequiredOutputs(1); this->SetNthOutput(0, output.GetPointer()); } mitk::SimulationReader::~SimulationReader() { } void mitk::SimulationReader::GenerateData() { Simulation::Pointer simulation = static_cast(this->GetOutput()); - sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSimulation(); + sofa::simulation::Simulation::SPtr sofaSimulation = simulation->GetSOFASimulation(); ISimulationService* simulationService = GetSimulationService(); - Simulation::Pointer currentSimulation = simulationService->GetSimulation(); + Simulation::Pointer lastActiveSimulation = simulationService->GetActiveSimulation(); - simulationService->SetSimulation(simulation); + simulationService->SetActiveSimulation(simulation); + + std::ifstream scnFile(m_FileName.c_str()); + std::string content = std::string((std::istreambuf_iterator(scnFile)), std::istreambuf_iterator()); + scnFile.close(); + + std::istringstream stream(content); + std::string firstLine; + + if (!std::getline(stream, firstLine).good()) + mitkThrow() << "Could not load '" << m_FileName << "'!"; + + std::string originalPath; + + if (firstLine.size() > 21 && firstLine.substr(0, 21) == "\n"; + + std::ofstream scnFile(m_FileName.c_str()); + scnFile << originalPath << simulation->GetProperty("Scene File")->GetValueAsString(); +} + +mitk::Simulation* mitk::SimulationWriter::GetInput() +{ + if (this->GetNumberOfInputs() == 0) + return NULL; + + return dynamic_cast(this->GetInput(0)); +} + +void mitk::SimulationWriter::SetInput(Simulation *simulation) +{ + this->SetNthInput(0, simulation); +} + +const char* mitk::SimulationWriter::GetFileName() const +{ + return m_FileName.c_str(); +} + +void mitk::SimulationWriter::SetFileName(const char* fileName) +{ + m_FileName = fileName; +} + +const char* mitk::SimulationWriter::GetFilePrefix() const +{ + return m_FilePrefix.c_str(); +} + +void mitk::SimulationWriter::SetFilePrefix(const char* filePrefix) +{ + m_FilePrefix = filePrefix; +} + +const char* mitk::SimulationWriter::GetFilePattern() const +{ + return m_FilePattern.c_str(); +} + +void mitk::SimulationWriter::SetFilePattern(const char* filePattern) +{ + m_FilePattern = filePattern; +} + +std::string mitk::SimulationWriter::GetFileExtension() +{ + return m_FileExtension; +} + +std::vector mitk::SimulationWriter::GetPossibleFileExtensions() +{ + std::vector possibleFileExtensions; + possibleFileExtensions.push_back(m_FileExtension); + return possibleFileExtensions; +} + +std::string mitk::SimulationWriter::GetWritenMIMEType() +{ + return m_MIMEType; +} + +bool mitk::SimulationWriter::CanWriteDataType(DataNode* dataNode) +{ + if (dataNode == NULL) + return false; + + return this->CanWriteBaseDataType(dataNode->GetData()); +} + +const char* mitk::SimulationWriter::GetDefaultFilename() +{ + std::string defaultFilename = "Simulation" + m_FileExtension; + return defaultFilename.c_str(); +} + +const char* mitk::SimulationWriter::GetFileDialogPattern() +{ + std::string fileDialogPattern = "SOFA Scene Files (*" + m_FileExtension + ")"; + return fileDialogPattern.c_str(); +} + +const char* mitk::SimulationWriter::GetDefaultExtension() +{ + return m_FileExtension.c_str(); +} + +bool mitk::SimulationWriter::CanWriteBaseDataType(BaseData::Pointer data) +{ + if (data.IsNull()) + return false; + + return dynamic_cast(data.GetPointer()) != NULL; +} + +void mitk::SimulationWriter::DoWrite(BaseData::Pointer data) +{ + if (this->CanWriteBaseDataType(data)) + { + this->SetNthInput(0, dynamic_cast(data.GetPointer())); + this->Update(); + } +} diff --git a/Modules/Simulation/mitkSimulationWriter.h b/Modules/Simulation/mitkSimulationWriter.h new file mode 100644 index 0000000000..b94aa4e4be --- /dev/null +++ b/Modules/Simulation/mitkSimulationWriter.h @@ -0,0 +1,77 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkSimulationWriter_h +#define mitkSimulationWriter_h + +#include +#include + +namespace mitk +{ + class Simulation; + + class MitkSimulation_EXPORT SimulationWriter : public FileWriterWithInformation + { + public: + mitkClassMacro(SimulationWriter, FileWriterWithInformation); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); + + using Superclass::SetInput; + void SetInput(Simulation* simulation); + + // mitk::FileWriter interface + + mitkWriterMacro; + using Superclass::GetInput; + Simulation* GetInput(); + + const char* GetFileName() const; + void SetFileName(const char* fileName); + const char* GetFilePrefix() const; + void SetFilePrefix(const char* filePrefix); + const char* GetFilePattern() const; + void SetFilePattern(const char* filePattern); + std::string GetFileExtension(); + std::vector GetPossibleFileExtensions(); + std::string GetWritenMIMEType(); + bool CanWriteDataType(DataNode* dataNode); + + // mitk::FileWriterWithInformation interface + + const char* GetDefaultFilename(); + const char* GetFileDialogPattern(); + const char* GetDefaultExtension(); + bool CanWriteBaseDataType(BaseData::Pointer data); + void DoWrite(BaseData::Pointer data); + + protected: + SimulationWriter(); + ~SimulationWriter(); + + void GenerateData(); + + private: + std::string m_FileName; + std::string m_FilePrefix; + std::string m_FilePattern; + std::string m_FileExtension; + std::string m_MIMEType; + }; +} + +#endif diff --git a/Modules/Simulation/mitkSimulationWriterFactory.cpp b/Modules/Simulation/mitkSimulationWriterFactory.cpp new file mode 100644 index 0000000000..eb0b7d9f4b --- /dev/null +++ b/Modules/Simulation/mitkSimulationWriterFactory.cpp @@ -0,0 +1,70 @@ +/*=================================================================== + +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 "mitkSimulationWriterFactory.h" +#include +#include + +namespace mitk +{ + template + class CreateSimulationWriterFunction : public itk::CreateObjectFunctionBase + { + public: + mitkClassMacro(CreateSimulationWriterFunction, itk::CreateObjectFunctionBase); + itkFactorylessNewMacro(Self); + + itk::LightObject::Pointer CreateObject() + { + typename T::Pointer simulationWriter = T::New(); + simulationWriter->Register(); + return simulationWriter.GetPointer(); + } + + protected: + CreateSimulationWriterFunction() + { + } + + ~CreateSimulationWriterFunction() + { + } + }; +} + +mitk::SimulationWriterFactory::SimulationWriterFactory() +{ + this->RegisterOverride( + "IOWriter", + "SimulationWriter", + "SOFA scene file writer", + true, + CreateSimulationWriterFunction::New()); +} + +mitk::SimulationWriterFactory::~SimulationWriterFactory() +{ +} + +const char* mitk::SimulationWriterFactory::GetITKSourceVersion() const +{ + return ITK_SOURCE_VERSION; +} + +const char* mitk::SimulationWriterFactory::GetDescription() const +{ + return "SimulationWriterFactory"; +} diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkSimulationWriterFactory.h similarity index 51% copy from Modules/Simulation/mitkSimulationService.h copy to Modules/Simulation/mitkSimulationWriterFactory.h index c8c3803fb8..53f8a36421 100644 --- a/Modules/Simulation/mitkSimulationService.h +++ b/Modules/Simulation/mitkSimulationWriterFactory.h @@ -1,38 +1,41 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef mitkSimulationService_h -#define mitkSimulationService_h +#ifndef mitkSimulationWriterFactory_h +#define mitkSimulationWriterFactory_h -#include +#include +#include +#include namespace mitk { - class SimulationService : public ISimulationService + class MitkSimulation_EXPORT SimulationWriterFactory : public itk::ObjectFactoryBase { public: - SimulationService(); - ~SimulationService(); + mitkClassMacro(SimulationWriterFactory, itk::ObjectFactoryBase); + itkFactorylessNewMacro(Self); - Simulation::Pointer GetSimulation() const; - void SetSimulation(Simulation::Pointer simulation); + const char* GetITKSourceVersion() const; + const char* GetDescription() const; - private: - Simulation::Pointer m_Simulation; + protected: + SimulationWriterFactory(); + ~SimulationWriterFactory(); }; } #endif diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp index 57da5bf2f0..27fdb4cd97 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.cpp @@ -1,66 +1,86 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGetSimulationService.h" #include "mitkISimulationService.h" #include "mitkVtkSimulationPolyDataMapper.h" #include #include #include #include namespace mitk { vtkStandardNewMacro(vtkSimulationPolyDataMapper); } mitk::vtkSimulationPolyDataMapper::vtkSimulationPolyDataMapper() : m_SimulationService(GetSimulationService()) { } mitk::vtkSimulationPolyDataMapper::~vtkSimulationPolyDataMapper() { } void mitk::vtkSimulationPolyDataMapper::Render(vtkRenderer* renderer, vtkActor* actor) { if (renderer->GetRenderWindow()->CheckAbortStatus()) return; if (m_Simulation.IsNull()) return; renderer->GetRenderWindow()->MakeCurrent(); - m_SimulationService->SetSimulation(m_Simulation); + m_SimulationService->SetActiveSimulation(m_Simulation); sofa::core::visual::VisualParams* vParams = sofa::core::visual::VisualParams::defaultInstance(); - sofa::simulation::Simulation::SPtr sofaSimulation = m_Simulation->GetSimulation(); + sofa::simulation::Simulation::SPtr sofaSimulation = m_Simulation->GetSOFASimulation(); sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode(); sofaSimulation->updateVisual(rootNode.get()); sofaSimulation->draw(vParams, rootNode.get()); } void mitk::vtkSimulationPolyDataMapper::RenderPiece(vtkRenderer*, vtkActor*) { } void mitk::vtkSimulationPolyDataMapper::SetSimulation(Simulation::Pointer simulation) { m_Simulation = simulation; } + +double* mitk::vtkSimulationPolyDataMapper::GetBounds() +{ + if (m_Simulation.IsNull()) + return Superclass::GetBounds(); + + sofa::simulation::Node::SPtr rootNode = m_Simulation->GetRootNode(); + const sofa::defaulttype::BoundingBox& bbox = rootNode->f_bbox.getValue(); + const sofa::defaulttype::Vector3& min = bbox.minBBox(); + const sofa::defaulttype::Vector3& max = bbox.maxBBox(); + + Bounds[0] = min.x(); + Bounds[1] = max.x(); + Bounds[2] = min.y(); + Bounds[3] = max.y(); + Bounds[4] = min.z(); + Bounds[5] = max.z(); + + return this->Bounds; +} diff --git a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h index fbfa866325..1590536318 100644 --- a/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h +++ b/Modules/Simulation/mitkVtkSimulationPolyDataMapper.h @@ -1,47 +1,48 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkVtkSimulationPolyDataMapper_h #define mitkVtkSimulationPolyDataMapper_h #include #include #include namespace mitk { class ISimulationService; class MitkSimulation_EXPORT vtkSimulationPolyDataMapper : public vtkPolyDataMapper { public: static vtkSimulationPolyDataMapper* New(); vtkTypeMacro(vtkSimulationPolyDataMapper, vtkPolyDataMapper); + double* GetBounds(); void Render(vtkRenderer* renderer, vtkActor* actor); void RenderPiece(vtkRenderer*, vtkActor*); void SetSimulation(mitk::Simulation::Pointer simulation); private: vtkSimulationPolyDataMapper(); ~vtkSimulationPolyDataMapper(); Simulation::Pointer m_Simulation; ISimulationService* m_SimulationService; }; } #endif diff --git a/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp new file mode 100644 index 0000000000..2dded5961b --- /dev/null +++ b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.cpp @@ -0,0 +1,60 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkSchedulableProcess.h" +#include "mitkWeightedRoundRobinSchedulingAlgorithm.h" +#include + +static bool CompareElapsedTime(mitk::SchedulableProcess* lhs, mitk::SchedulableProcess* rhs) +{ + return lhs->GetElapsedTime() < rhs->GetElapsedTime(); +} + +mitk::WeightedRoundRobinSchedulingAlgorithm::WeightedRoundRobinSchedulingAlgorithm() +{ +} + +mitk::WeightedRoundRobinSchedulingAlgorithm::~WeightedRoundRobinSchedulingAlgorithm() +{ +} + +mitk::SchedulableProcess* mitk::WeightedRoundRobinSchedulingAlgorithm::GetNextProcess(std::vector& processQueue) +{ + const double threshold = 1.5; + size_t numProcesses = processQueue.size(); + + if (numProcesses == 0) + return NULL; + + boost::chrono::nanoseconds maxElapsedTime = (*std::max_element(processQueue.begin(), processQueue.end(), CompareElapsedTime))->GetElapsedTime(); + mitk::SchedulableProcess* process = processQueue[0]; + + if (numProcesses > 1) + { + boost::chrono::nanoseconds totalElapsedTime = process->GetTotalElapsedTime(); + boost::chrono::nanoseconds elapsedTime = process->GetElapsedTime(); + + if (totalElapsedTime >= maxElapsedTime || totalElapsedTime + elapsedTime >= maxElapsedTime * threshold) + { + process->ResetTotalElapsedTime(); + + processQueue.erase(processQueue.begin()); + processQueue.push_back(process); + } + } + + return process; +} diff --git a/Modules/Simulation/mitkSimulationService.h b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h similarity index 57% copy from Modules/Simulation/mitkSimulationService.h copy to Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h index c8c3803fb8..53af49ceca 100644 --- a/Modules/Simulation/mitkSimulationService.h +++ b/Modules/Simulation/mitkWeightedRoundRobinSchedulingAlgorithm.h @@ -1,38 +1,34 @@ /*=================================================================== 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 mitkSimulationService_h -#define mitkSimulationService_h +#ifndef mitkWeightedRoundRobinSchedulingAlgorithm_h +#define mitkWeightedRoundRobinSchedulingAlgorithm_h -#include +#include "mitkSchedulingAlgorithmBase.h" namespace mitk { - class SimulationService : public ISimulationService + class WeightedRoundRobinSchedulingAlgorithm : public SchedulingAlgorithmBase { public: - SimulationService(); - ~SimulationService(); + WeightedRoundRobinSchedulingAlgorithm(); + ~WeightedRoundRobinSchedulingAlgorithm(); - Simulation::Pointer GetSimulation() const; - void SetSimulation(Simulation::Pointer simulation); - - private: - Simulation::Pointer m_Simulation; + SchedulableProcess* GetNextProcess(std::vector& processQueue); }; } #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt index a4b3d17818..12c8c7349f 100644 --- a/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt +++ b/Plugins/org.mitk.gui.qt.simulation/CMakeLists.txt @@ -1,7 +1,11 @@ project(org_mitk_gui_qt_simulation) MACRO_CREATE_MITK_CTK_PLUGIN( EXPORT_DIRECTIVE SIMULATION_EXPORT EXPORTED_INCLUDE_SUFFIXES src MODULE_DEPENDS MitkQtWidgets MitkSimulation ) + +if(MSVC) + set_property(TARGET ${PLUGIN_TARGET} APPEND_STRING PROPERTY COMPILE_FLAGS " /wd4250 /wd4251 /wd4267 /wd4275") +endif() \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.simulation/files.cmake b/Plugins/org.mitk.gui.qt.simulation/files.cmake index b9f3403b63..744bd1618c 100644 --- a/Plugins/org.mitk.gui.qt.simulation/files.cmake +++ b/Plugins/org.mitk.gui.qt.simulation/files.cmake @@ -1,39 +1,47 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_simulation_Activator.cpp + QmitkBaseItemDelegate.cpp + QmitkBaseTreeWidget.cpp + QmitkNoEditItemDelegate.cpp + QmitkSceneTreeWidget.cpp QmitkSimulationPreferencePage.cpp QmitkSimulationView.cpp ) set(UI_FILES src/internal/QmitkSimulationPreferencePageControls.ui src/internal/QmitkSimulationViewControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_simulation_Activator.h + src/internal/QmitkBaseItemDelegate.h + src/internal/QmitkBaseTreeWidget.h + src/internal/QmitkNoEditItemDelegate.h + src/internal/QmitkSceneTreeWidget.h src/internal/QmitkSimulationPreferencePage.h src/internal/QmitkSimulationView.h ) set(CACHED_RESOURCE_FILES resources/SOFAIcon.png plugin.xml ) set(QRC_FILES resources/Simulation.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach() foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach() diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png new file mode 100644 index 0000000000..558445718c Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Node_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png new file mode 100644 index 0000000000..4832b76336 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Object_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc index 53480e1d88..2684648ed4 100644 --- a/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc +++ b/Plugins/org.mitk.gui.qt.simulation/resources/Simulation.qrc @@ -1,5 +1,8 @@ - SOFAIcon.png + Node_16x16.png + Object_16x16.png + Slave_16x16.png + SOFAIcon.png diff --git a/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png new file mode 100644 index 0000000000..9281fff450 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.simulation/resources/Slave_16x16.png differ diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp new file mode 100644 index 0000000000..dfc589a25d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.cpp @@ -0,0 +1,77 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "QmitkBaseItemDelegate.h" +#include + +using namespace sofa::defaulttype; +using namespace sofa::core::objectmodel; + +static inline BaseData* GetBaseData(const QModelIndex& index) +{ + return index.data(Qt::UserRole).value(); +} + +QmitkBaseItemDelegate::QmitkBaseItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} + +QmitkBaseItemDelegate::~QmitkBaseItemDelegate() +{ +} + +QWidget* QmitkBaseItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + BaseData* baseData = GetBaseData(index); + const AbstractTypeInfo* typeInfo = baseData->getValueTypeInfo(); + + if (typeInfo->name() == "bool") + { + assert(false && "Bool type is directly handled by QmitkBaseTreeWidget!"); + } + else if (typeInfo->size() == 1) + { + if (typeInfo->Integer() || typeInfo->Scalar() || typeInfo->Text()) + { + // TODO: TagSet + return QStyledItemDelegate::createEditor(parent, option, index); + } + + // TODO + } + else + { + // TODO + } + + return NULL; +} + +void QmitkBaseItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QStyledItemDelegate::paint(painter, option, index); +} + +void QmitkBaseItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +{ + QStyledItemDelegate::setEditorData(editor, index); +} + +void QmitkBaseItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h new file mode 100644 index 0000000000..01a009a16d --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h @@ -0,0 +1,49 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkBaseItemDelegate_h +#define QmitkBaseItemDelegate_h + +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class BaseData; + } + } +} + +class QmitkBaseItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit QmitkBaseItemDelegate(QObject* parent = NULL); + ~QmitkBaseItemDelegate(); + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void setEditorData(QWidget* editor, const QModelIndex& index) const; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; +}; + +Q_DECLARE_METATYPE(sofa::core::objectmodel::BaseData*) + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp new file mode 100644 index 0000000000..60fa449d06 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.cpp @@ -0,0 +1,115 @@ +/*=================================================================== + +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 "QmitkBaseTreeWidget.h" +#include "QmitkBaseItemDelegate.h" +#include "QmitkNoEditItemDelegate.h" +#include "QmitkSceneTreeWidget.h" + +QmitkBaseTreeWidget::QmitkBaseTreeWidget(QWidget* parent) + : QTreeWidget(parent), + m_Base(NULL) +{ + this->setItemDelegateForColumn(0, new QmitkNoEditItemDelegate); + this->setItemDelegateForColumn(1, new QmitkBaseItemDelegate); + + this->setSortingEnabled(true); + this->header()->setSortIndicator(0, Qt::AscendingOrder); +} + +QmitkBaseTreeWidget::~QmitkBaseTreeWidget() +{ +} + +void QmitkBaseTreeWidget::clear() +{ + m_Base = NULL; + m_GroupItemMap.clear(); + + QTreeWidget::clear(); +} + +void QmitkBaseTreeWidget::OnSelectedBaseChanged(Base* base) +{ + this->clear(); + + m_Base = base; + + if (base != NULL) + this->FillTreeWidget(); +} + +void QmitkBaseTreeWidget::FillTreeWidget() +{ + const Base::VecData& dataFields = m_Base->getDataFields(); + + for (Base::VecData::const_iterator dataField = dataFields.begin(); dataField != dataFields.end(); ++dataField) + { + if (!(*dataField)->isDisplayed()) + continue; + + QString name = QString::fromStdString((*dataField)->getName()); + + if (name.isEmpty()) + continue; + + QString group = (*dataField)->getGroup(); + + if (!group.isEmpty() && !m_GroupItemMap.contains(group)) + m_GroupItemMap.insert(group, new QTreeWidgetItem(this, QStringList() << group)); + + QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() << name); + item->setToolTip(0, (*dataField)->getHelp()); + + item->setFlags(!(*dataField)->isReadOnly() + ? item->flags() | Qt::ItemIsEditable + : Qt::ItemIsSelectable); + + QString type = QString::fromStdString((*dataField)->getValueTypeString()); + + if (type == "bool") + { + item->setFlags((item->flags() & ~Qt::EditRole) | Qt::ItemIsUserCheckable); + item->setCheckState(1, (*dataField)->getValueString() == "1" ? Qt::Checked : Qt::Unchecked); + } + else + { + if (type == "double" || type == "float" || type == "int" || type == "string" || type == "unsigned int") + { + item->setData(1, Qt::DisplayRole, QVariant::fromValue(QString::fromStdString((*dataField)->getValueString()))); + } + else + { + item->setData(1, Qt::DisplayRole, QVariant::fromValue("[" + type + "]")); + } + + item->setData(1, Qt::UserRole, QVariant::fromValue(*dataField)); + } + + if (group.isEmpty()) + { + this->addTopLevelItem(item); + } + else + { + m_GroupItemMap[group]->addChild(item); + } + } + + this->setRootIsDecorated(!m_GroupItemMap.isEmpty()); + this->expandAll(); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h new file mode 100644 index 0000000000..0aed7ef6c6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseTreeWidget.h @@ -0,0 +1,60 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkBaseTreeWidget_h +#define QmitkBaseTreeWidget_h + +#include +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class Base; + } + } +} + +class QmitkSceneTreeWidget; + +class QmitkBaseTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + typedef sofa::core::objectmodel::Base Base; + + explicit QmitkBaseTreeWidget(QWidget* parent = NULL); + ~QmitkBaseTreeWidget(); + + // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ///////////////// + void clear(); + ///////////////////////////////////////////////////////////////////////////// + +public slots: + void OnSelectedBaseChanged(Base* base); + +private: + void FillTreeWidget(); + + Base* m_Base; + QMap m_GroupItemMap; +}; + +#endif diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp similarity index 61% rename from Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp index 5f283e790a..7d2d6733ed 100644 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.cpp @@ -1,28 +1,31 @@ /*=================================================================== 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 mitkGetSimulationDataNode_h -#define mitkGetSimulationDataNode_h +#include "QmitkNoEditItemDelegate.h" -#include -#include +QmitkNoEditItemDelegate::QmitkNoEditItemDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} -namespace mitk +QmitkNoEditItemDelegate::~QmitkNoEditItemDelegate() { - DataNode::Pointer GetSimulationDataNode(sofa::core::objectmodel::BaseNode::SPtr rootNode); } -#endif +QWidget* QmitkNoEditItemDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const +{ + return NULL; +} diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h similarity index 57% rename from Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h rename to Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h index f99fdb6099..e1d2477073 100644 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkNoEditItemDelegate.h @@ -1,27 +1,33 @@ /*=================================================================== 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 mitkGetDataStorage_h -#define mitkGetDataStorage_h +#ifndef QmitkNoEditItemDelegate_h +#define QmitkNoEditItemDelegate_h -#include +#include -namespace mitk +class QmitkNoEditItemDelegate : public QStyledItemDelegate { - DataStorage::Pointer GetDataStorage(); -} + Q_OBJECT + +public: + explicit QmitkNoEditItemDelegate(QObject* parent = NULL); + ~QmitkNoEditItemDelegate(); + + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp new file mode 100644 index 0000000000..f6938c7ed0 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.cpp @@ -0,0 +1,384 @@ +/*=================================================================== + +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 "QmitkSceneTreeWidget.h" +#include +#include +#include +#include + +template +static inline T* as(QmitkSceneTreeWidget::Base* base) +{ + return dynamic_cast(base); +} + +template +static inline bool is(QmitkSceneTreeWidget::Base* base) +{ + return dynamic_cast(base) != NULL; +} + +template +static inline bool is(QmitkSceneTreeWidget::Base* base) +{ + return is(base) || is(base); +} + +template +static inline bool is(QmitkSceneTreeWidget::Base* base) +{ + return is(base) || is(base) || is(base); +} + +static inline bool isBaseInteractionForceField(QmitkSceneTreeWidget::Base* base) +{ + sofa::core::behavior::BaseInteractionForceField* iff = dynamic_cast(base); + return iff != NULL && iff->getMechModel1() != iff->getMechModel2(); +} + +static inline bool isMechanicalMapping(QmitkSceneTreeWidget::Base* base) +{ + sofa::core::BaseMapping* mm = dynamic_cast(base); + return mm != NULL && mm->isMechanical(); +} + +static QRgb GetColor(QmitkSceneTreeWidget::Base* base) +{ + using namespace sofa::core; + using namespace sofa::core::behavior; + using namespace sofa::core::collision; + using namespace sofa::core::loader; + using namespace sofa::core::objectmodel; + using namespace sofa::core::topology; + using namespace sofa::core::visual; + using namespace sofa::simulation::Colors; + + QString hexColor; + + if (is(base)) + { + hexColor = COLOR[NODE]; + } + else if (is(base)) + { + if (is(base)) + hexColor = COLOR[sofa::simulation::Colors::CONTEXT]; + else if (is(base)) + hexColor = COLOR[BMODEL]; + else if (is(base)) + hexColor = COLOR[CMODEL]; + else if (is(base)) + hexColor = COLOR[MMODEL]; + else if (is(base)) + hexColor = COLOR[PROJECTIVECONSTRAINTSET]; + else if (is(base)) + hexColor = COLOR[CONSTRAINTSET]; + else if (is(base)) + hexColor = COLOR[MASS]; + else if (isBaseInteractionForceField(base)) + hexColor = COLOR[IFFIELD]; + else if (is(base)) + hexColor = COLOR[FFIELD]; + else if (is(base)) + hexColor = COLOR[SOLVER]; + else if (is(base)) + hexColor = COLOR[COLLISION]; + else if (isMechanicalMapping(base)) + hexColor = COLOR[MMAPPING]; + else if (is(base)) + hexColor = COLOR[MAPPING]; + else if (is(base)) + hexColor = COLOR[TOPOLOGY]; + else if (is(base)) + hexColor = COLOR[LOADER]; + else if (is(base)) + hexColor = COLOR[CONFIGURATIONSETTING]; + else if (is(base)) + hexColor = COLOR[VMODEL]; + else + hexColor = COLOR[OBJECT]; + } + else + { + hexColor = "#000"; + } + + QColor color; + color.setNamedColor(hexColor); + + return color.rgb(); +} + +static QPixmap ReplaceColor(const QPixmap& pixmap, QRgb from, QRgb to) +{ + QImage image = pixmap.toImage(); + + const int width = image.width(); + const int height = image.height(); + int x, y; + + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + { + if (image.pixel(x, y) == from) + image.setPixel(x, y, to); + } + } + + return QPixmap::fromImage(image); +} + +static inline QIcon CreateObjectIcon(QmitkSceneTreeWidget::Base* base) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Object"), 0xff00ff00, GetColor(base))); +} + +static inline QIcon CreateNodeIcon(QmitkSceneTreeWidget::BaseNode* node) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Node"), 0xff00ff00, GetColor(node))); +} + +static inline QIcon CreateSlaveIcon(QmitkSceneTreeWidget::Base* base) +{ + return QIcon(ReplaceColor(QPixmap(":/Simulation/Slave"), 0xff00ff00, GetColor(base))); +} + +static inline QString GetName(QmitkSceneTreeWidget::Base* base) +{ + return QString::fromStdString(base->getName()); +} + +static inline QString GetClassName(QmitkSceneTreeWidget::Base* base) +{ + return QString::fromStdString(base->getClassName()); +} + +QmitkSceneTreeWidget::QmitkSceneTreeWidget(QWidget* parent) + : QTreeWidget(parent) +{ +} + +QmitkSceneTreeWidget::~QmitkSceneTreeWidget() +{ +} + +void QmitkSceneTreeWidget::clear() +{ + QTreeWidgetItem* rootItem = this->topLevelItem(0); + + if (rootItem != NULL) + this->removeChild(NULL, as(m_ItemBaseMap[rootItem])); + + this->ClearMaps(); + + QTreeWidget::clear(); +} + +void QmitkSceneTreeWidget::addChild(Node* parent, Node* child) +{ + assert(child != NULL && "Child node is NULL!"); + assert(!m_BaseItemMap.contains(child) && "TODO: Support nodes with multiple parents!"); + + QTreeWidgetItem* item; + + if (parent == NULL) + { + item = new QTreeWidgetItem(QStringList() << GetName(child)); + this->addTopLevelItem(item); + } + else + { + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(child)); + } + + item->setIcon(0, CreateNodeIcon(child)); + this->InsertIntoMaps(child, item); + + MutationListener::addChild(parent, child); +} + +void QmitkSceneTreeWidget::removeChild(Node* parent, Node* child) +{ + assert(child != NULL && "Child node is NULL!"); + assert(m_BaseItemMap.contains(child) && "Child node has already been removed!"); + + MutationListener::removeChild(parent, child); + + if (parent == NULL) + { + delete m_BaseItemMap[child]; + } + else + { + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + m_BaseItemMap[parent]->removeChild(m_BaseItemMap[child]); + } + + this->RemoveFromMaps(child); +} + +void QmitkSceneTreeWidget::moveChild(Node* previous, Node* parent, Node* child) +{ + if (previous == NULL) + { + this->addChild(parent, child); + } + else if (parent == NULL) + { + this->removeChild(previous, child); + } + else + { + assert(child != NULL && "Child node is NULL!"); + assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(child) && "Unknown child node!"); + + QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; + m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[child]))); + } +} + +void QmitkSceneTreeWidget::addObject(Node* parent, BaseObject* object) +{ + assert(parent != NULL && "Parent node is NULL!"); + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + // assert(!m_BaseItemMap.contains(object) && "Object has already been added!"); + + if (!m_BaseItemMap.contains(object)) + { + QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[parent], QStringList() << GetName(object)); + item->setToolTip(0, GetClassName(object)); + item->setIcon(0, CreateObjectIcon(object)); + this->InsertIntoMaps(object, item); + } + + MutationListener::addObject(parent, object); +} + +void QmitkSceneTreeWidget::removeObject(Node* parent, BaseObject* object) +{ + assert(parent != NULL && "Parent node is NULL!"); + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(object) && "Object has already been removed!"); + + MutationListener::removeObject(parent, object); + + m_BaseItemMap[parent]->removeChild(m_BaseItemMap[object]); + this->RemoveFromMaps(object); +} + +void QmitkSceneTreeWidget::moveObject(Node* previous, Node* parent, BaseObject* object) +{ + if (previous == NULL) + { + this->addObject(parent, object); + } + else if (parent == NULL) + { + this->removeObject(previous, object); + } + else + { + assert(object != NULL && "Object is NULL!"); + assert(m_BaseItemMap.contains(previous) && "Unknown previous parent node!"); + assert(m_BaseItemMap.contains(parent) && "Unknown parent node!"); + assert(m_BaseItemMap.contains(object) && "Unknown object!"); + + QTreeWidgetItem* previousItem = m_BaseItemMap[previous]; + m_BaseItemMap[parent]->addChild(previousItem->takeChild(previousItem->indexOfChild(m_BaseItemMap[object]))); + } +} + +void QmitkSceneTreeWidget::addSlave(BaseObject* master, BaseObject* slave) +{ + assert(master != NULL && "Master object is NULL!"); + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(!m_BaseItemMap.contains(slave) && "Slave object has already been added!"); + + QTreeWidgetItem* item = new QTreeWidgetItem(m_BaseItemMap[master], QStringList() << GetName(slave)); + item->setToolTip(0, GetClassName(slave)); + item->setIcon(0, CreateSlaveIcon(slave)); + this->InsertIntoMaps(slave, item); + + MutationListener::addSlave(master, slave); +} + +void QmitkSceneTreeWidget::removeSlave(BaseObject* master, BaseObject* slave) +{ + assert(master != NULL && "Master object is NULL!"); + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(m_BaseItemMap.contains(slave) && "Slave object has already been removed!"); + + MutationListener::removeSlave(master, slave); + + m_BaseItemMap[master]->removeChild(m_BaseItemMap[slave]); + this->RemoveFromMaps(slave); +} + +void QmitkSceneTreeWidget::moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave) +{ + if (previousMaster == NULL) + { + this->addSlave(master, slave); + } + else if (master == NULL) + { + this->removeSlave(previousMaster, slave); + } + else + { + assert(slave != NULL && "Slave object is NULL!"); + assert(m_BaseItemMap.contains(previousMaster) && "Unknown previous master object!"); + assert(m_BaseItemMap.contains(master) && "Unknown master object!"); + assert(m_BaseItemMap.contains(slave) && "Unknown slave object!"); + + QTreeWidgetItem* previousMasterItem = m_BaseItemMap[previousMaster]; + m_BaseItemMap[master]->addChild(previousMasterItem->takeChild(previousMasterItem->indexOfChild(m_BaseItemMap[slave]))); + } +} + +QmitkSceneTreeWidget::Base* QmitkSceneTreeWidget::GetBaseFromItem(QTreeWidgetItem* item) const +{ + return m_ItemBaseMap.contains(item) + ? m_ItemBaseMap[item] + : NULL; +} + +void QmitkSceneTreeWidget::ClearMaps() +{ + m_BaseItemMap.clear(); + m_ItemBaseMap.clear(); +} + +void QmitkSceneTreeWidget::InsertIntoMaps(Base* base, QTreeWidgetItem* item) +{ + m_BaseItemMap.insert(base, item); + m_ItemBaseMap.insert(item, base); +} + +void QmitkSceneTreeWidget::RemoveFromMaps(Base* base) +{ + m_ItemBaseMap.remove(m_BaseItemMap[base]); + m_BaseItemMap.remove(base); +} diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h new file mode 100644 index 0000000000..ae104ced87 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSceneTreeWidget.h @@ -0,0 +1,82 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkSceneTreeWidget_h +#define QmitkSceneTreeWidget_h + +#include +#include +#include + +namespace sofa +{ + namespace core + { + namespace objectmodel + { + class Base; + class BaseNode; + class BaseObject; + } + } + + namespace simulation + { + class Node; + } +} + +class QmitkSceneTreeWidget : public QTreeWidget, public sofa::simulation::MutationListener +{ + Q_OBJECT + +public: + typedef sofa::core::objectmodel::Base Base; + typedef sofa::core::objectmodel::BaseNode BaseNode; + typedef sofa::core::objectmodel::BaseObject BaseObject; + typedef sofa::simulation::Node Node; + + explicit QmitkSceneTreeWidget(QWidget* parent = NULL); + ~QmitkSceneTreeWidget(); + + Base* GetBaseFromItem(QTreeWidgetItem* item) const; + + // QTreeWidget, QTreeView, and QAbstractItemView Interfaces ///////////////// + void clear(); + ///////////////////////////////////////////////////////////////////////////// + + // MutationListener Interface /////////////////////////////////////////////// + void addChild(Node* parent, Node* child); + void removeChild(Node* parent, Node* child); + void moveChild(Node* previous, Node* parent, Node* child); + void addObject(Node* parent, BaseObject* object); + void removeObject(Node* parent, BaseObject* object); + void moveObject(Node* previous, Node* parent, BaseObject* object); + void addSlave(BaseObject* master, BaseObject* slave); + void removeSlave(BaseObject* master, BaseObject* slave); + void moveSlave(BaseObject* previousMaster, BaseObject* master, BaseObject* slave); + ///////////////////////////////////////////////////////////////////////////// + +private: + void ClearMaps(); + void InsertIntoMaps(Base* base, QTreeWidgetItem* item); + void RemoveFromMaps(Base* base); + + QMap m_BaseItemMap; + QMap m_ItemBaseMap; +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp index ba278290f9..07b79e9e8b 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.cpp @@ -1,234 +1,301 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "org_mitk_gui_qt_simulation_Activator.h" +#include "QmitkBaseItemDelegate.h" +#include "QmitkNoEditItemDelegate.h" #include "QmitkSimulationView.h" -#include -#include #include #include +#include #include +#include template static T* GetService() { ctkPluginContext* context = mitk::org_mitk_gui_qt_simulation_Activator::GetContext(); if (context == NULL) return NULL; ctkServiceReference serviceReference = context->getServiceReference(); return serviceReference ? context->getService(serviceReference) : NULL; } +static mitk::SimulationInteractor::Pointer CreateSimulationInteractor() +{ + const us::Module* simulationModule = us::ModuleRegistry::GetModule("MitkSimulation"); + + mitk::SimulationInteractor::Pointer interactor = mitk::SimulationInteractor::New(); + interactor->LoadStateMachine("Simulation.xml", simulationModule); + interactor->SetEventConfig("SimulationConfig.xml", simulationModule); + + return interactor; +} + QmitkSimulationView::QmitkSimulationView() : m_SimulationService(GetService()), - m_SelectionWasRemovedFromDataStorage(false), + m_Interactor(CreateSimulationInteractor()), m_Timer(this) { this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); connect(&m_Timer, SIGNAL(timeout()), this, SLOT(OnTimeout())); } QmitkSimulationView::~QmitkSimulationView() { this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1(this, &QmitkSimulationView::OnNodeRemovedFromDataStorage)); } void QmitkSimulationView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); - m_Controls.sceneComboBox->SetDataStorage(this->GetDataStorage()); - m_Controls.sceneComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); - - m_Controls.stepsRecordedLabel->hide(); + m_Controls.simulationComboBox->SetDataStorage(this->GetDataStorage()); + m_Controls.simulationComboBox->SetPredicate(mitk::NodePredicateDataType::New("Simulation")); - connect(m_Controls.sceneComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSceneChanged(const mitk::DataNode*))); + connect(m_Controls.simulationComboBox, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnSelectedSimulationChanged(const mitk::DataNode*))); connect(m_Controls.animateButton, SIGNAL(toggled(bool)), this, SLOT(OnAnimateButtonToggled(bool))); connect(m_Controls.stepButton, SIGNAL(clicked()), this, SLOT(OnStepButtonClicked())); connect(m_Controls.resetButton, SIGNAL(clicked()), this, SLOT(OnResetButtonClicked())); connect(m_Controls.dtSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnDtChanged(double))); - connect(m_Controls.recordButton, SIGNAL(toggled(bool)), this, SLOT(OnRecordButtonToggled(bool))); - connect(m_Controls.snapshotButton, SIGNAL(clicked()), this, SLOT(OnSnapshotButtonClicked())); + connect(m_Controls.sceneTreeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(OnSelectedBaseChanged())); + connect(m_Controls.pushButton, SIGNAL(clicked()), this, SLOT(OnButtonClicked())); - if (m_Controls.sceneComboBox->GetSelectedNode().IsNotNull()) - this->OnSelectedSceneChanged(m_Controls.sceneComboBox->GetSelectedNode()); + if (m_Controls.simulationComboBox->GetSelectedNode().IsNotNull()) + { + this->OnSelectedSimulationChanged(m_Controls.simulationComboBox->GetSelectedNode()); + } + else + { + this->SetSimulationControlsEnabled(false); + } } void QmitkSimulationView::OnAnimateButtonToggled(bool toggled) { - if (this->SetSelectionAsCurrentSimulation()) + mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); + + if (toggled) { mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); - simulation->SetAnimationFlag(toggled); - if (toggled) - { - m_Controls.stepButton->setEnabled(false); - m_NextRenderWindowUpdate = QTime::currentTime().addMSecs(MsPerFrame); - m_Timer.start(0); - } + simulation->SetAnimationFlag(true); + scheduler->AddProcess(simulation); + + m_Controls.stepButton->setEnabled(false); } + else if (m_Selection.IsNotNull()) + { + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + + scheduler->RemoveProcess(simulation); + simulation->SetAnimationFlag(false); - if (!toggled) + m_Controls.stepButton->setEnabled(true); + } + + if (!scheduler->IsEmpty()) + { + if (!m_Timer.isActive()) + m_Timer.start(0); + } + else { m_Timer.stop(); - m_Controls.stepButton->setEnabled(true); } } void QmitkSimulationView::OnDtChanged(double dt) { - if (!this->SetSelectionAsCurrentSimulation()) + if (m_Selection.IsNull()) return; mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); simulation->SetDt(std::max(0.0, dt)); } void QmitkSimulationView::OnNodeRemovedFromDataStorage(const mitk::DataNode* node) { - if (m_Selection.IsNotNull() && m_Selection.GetPointer() == node) - m_SelectionWasRemovedFromDataStorage = true; -} + mitk::Simulation::Pointer simulation = dynamic_cast(node->GetData()); -void QmitkSimulationView::OnRecordButtonToggled(bool toggled) -{ - if (!toggled) + if (simulation.IsNotNull()) { + mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); - m_Controls.stepsRecordedLabel->hide(); - m_Controls.stepsRecordedLabel->setText("0 steps recorded"); - } - else - { - m_Controls.stepsRecordedLabel->show(); + scheduler->RemoveProcess(simulation); + + if (scheduler->IsEmpty() && m_Timer.isActive()) + m_Timer.stop(); + + if (m_SimulationService->GetActiveSimulation() == simulation) + m_SimulationService->SetActiveSimulation(NULL); } } void QmitkSimulationView::OnResetButtonClicked() { - if (!this->SetSelectionAsCurrentSimulation()) - return; - mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + m_SimulationService->SetActiveSimulation(simulation); m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); simulation->Reset(); this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } -void QmitkSimulationView::OnSelectedSceneChanged(const mitk::DataNode* node) +void QmitkSimulationView::OnSelectedSimulationChanged(const mitk::DataNode* node) { - if (m_Controls.animateButton->isChecked()) - m_Controls.animateButton->setChecked(false); - - if (m_SelectionWasRemovedFromDataStorage) - { - m_SelectionWasRemovedFromDataStorage = false; - m_Selection = NULL; - } - if (node != NULL) { - m_Selection = m_Controls.sceneComboBox->GetSelectedNode(); + m_Selection = m_Controls.simulationComboBox->GetSelectedNode(); mitk::Simulation* simulation = static_cast(m_Selection->GetData()); - m_SimulationService->SetSimulation(simulation); - - m_Controls.sceneGroupBox->setEnabled(true); - m_Controls.snapshotButton->setEnabled(true); + m_Controls.animateButton->setChecked(simulation->GetAnimationFlag()); m_Controls.dtSpinBox->setValue(simulation->GetRootNode()->getDt()); + this->SetSimulationControlsEnabled(true); } else { m_Selection = NULL; - m_SimulationService->SetSimulation(NULL); - - m_Controls.sceneGroupBox->setEnabled(false); - m_Controls.snapshotButton->setEnabled(false); + this->SetSimulationControlsEnabled(false); + m_Controls.animateButton->setChecked(false); m_Controls.dtSpinBox->setValue(0.0); } + + m_Interactor->SetDataNode(m_Selection); + + this->ResetSceneTreeWidget(); } -void QmitkSimulationView::OnSnapshotButtonClicked() +void QmitkSimulationView::OnSelectedBaseChanged() { - if (!this->SetSelectionAsCurrentSimulation()) - return; + QList selectedBaseItems = m_Controls.sceneTreeWidget->selectedItems(); - mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); - mitk::ExportMitkVisitor exportVisitor; - - simulation->GetRootNode()->executeVisitor(&exportVisitor); + m_Controls.baseTreeWidget->OnSelectedBaseChanged(!selectedBaseItems.isEmpty() + ? m_Controls.sceneTreeWidget->GetBaseFromItem(selectedBaseItems[0]) + : NULL); } void QmitkSimulationView::OnStep(bool renderWindowUpdate) { - if (!this->SetSelectionAsCurrentSimulation()) - return; + mitk::Scheduler* scheduler = m_SimulationService->GetScheduler(); + mitk::Simulation::Pointer simulation = dynamic_cast(scheduler->GetNextProcess()); - mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + m_SimulationService->SetActiveSimulation(simulation); - simulation->Animate(); + if (simulation.IsNotNull()) + simulation->Animate(); if (renderWindowUpdate) this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnStepButtonClicked() { - this->OnStep(true); -} + if (m_Selection.IsNull()) + return; -void QmitkSimulationView::SetFocus() -{ - m_Controls.animateButton->setFocus(); -} + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); -bool QmitkSimulationView::SetSelectionAsCurrentSimulation() const -{ - if (m_Selection.IsNotNull()) - { - m_SimulationService->SetSimulation(static_cast(m_Selection->GetData())); - return true; - } + m_SimulationService->SetActiveSimulation(simulation); + simulation->Animate(); - return false; + this->RequestRenderWindowUpdate(mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS); } void QmitkSimulationView::OnTimeout() { QTime currentTime = QTime::currentTime(); if (currentTime.msecsTo(m_NextRenderWindowUpdate) > 0) { this->OnStep(false); } else { - m_NextRenderWindowUpdate = currentTime.addMSecs(MsPerFrame); + m_NextRenderWindowUpdate = currentTime.addMSecs(MSecsPerFrame); this->OnStep(true); } } + +void QmitkSimulationView::ResetSceneTreeWidget() +{ + m_Controls.sceneTreeWidget->clear(); + + if (m_Selection.IsNull()) + return; + + mitk::Simulation::Pointer simulation = static_cast(m_Selection->GetData()); + + m_Controls.sceneTreeWidget->addChild(NULL, simulation->GetRootNode().get()); + m_Controls.sceneTreeWidget->expandItem(m_Controls.sceneTreeWidget->topLevelItem(0)); +} + +void QmitkSimulationView::SetSimulationControlsEnabled(bool enabled) +{ + m_Controls.animateButton->setEnabled(enabled); + m_Controls.stepButton->setEnabled(enabled); + m_Controls.resetButton->setEnabled(enabled); + m_Controls.dtLabel->setEnabled(enabled); + m_Controls.dtSpinBox->setEnabled(enabled); +} + +void QmitkSimulationView::SetFocus() +{ + m_Controls.animateButton->setFocus(); +} + +void QmitkSimulationView::OnButtonClicked() +{ +} + +/*#include +#include +#include +#include +#include + +void QmitkSimulationView::OnButtonClicked() +{ + vtkRenderWindow* renderWindow = this->GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetVtkRenderWindow(); + + vtkSmartPointer windowToImageFilter = vtkSmartPointer::New(); + + windowToImageFilter->SetInput(renderWindow); + windowToImageFilter->SetInputBufferTypeToZBuffer(); + + vtkSmartPointer imageShiftScaleFilter = vtkSmartPointer::New(); + + imageShiftScaleFilter->SetInputConnection(windowToImageFilter->GetOutputPort()); + imageShiftScaleFilter->SetOutputScalarTypeToUnsignedChar(); + imageShiftScaleFilter->SetShift(0); + imageShiftScaleFilter->SetScale(-255); + + vtkSmartPointer pngWriter = vtkSmartPointer::New(); + + pngWriter->SetInputConnection(imageShiftScaleFilter->GetOutputPort()); + pngWriter->SetFileName("C:\\Users\\Stefan\\Desktop\\DepthBuffer.png"); + pngWriter->Write(); +}*/ diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h index 8d6fe155b4..3eb8d7c803 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationView.h @@ -1,67 +1,68 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkSimulationView_h #define QmitkSimulationView_h -#include +#include #include #include #include #include namespace mitk { class ISimulationService; } class QmitkSimulationView : public QmitkAbstractView { Q_OBJECT public: QmitkSimulationView(); ~QmitkSimulationView(); void CreateQtPartControl(QWidget* parent); void SetFocus(); private slots: void OnAnimateButtonToggled(bool toggled); void OnDtChanged(double dt); - void OnRecordButtonToggled(bool toggled); void OnResetButtonClicked(); - void OnSelectedSceneChanged(const mitk::DataNode* node); - void OnSnapshotButtonClicked(); + void OnSelectedSimulationChanged(const mitk::DataNode* node); + void OnSelectedBaseChanged(); void OnStep(bool renderWindowUpdate); void OnStepButtonClicked(); void OnTimeout(); + void OnButtonClicked(); private: void OnNodeRemovedFromDataStorage(const mitk::DataNode* node); - bool SetSelectionAsCurrentSimulation() const; + void ResetSceneTreeWidget(); + void SetSimulationControlsEnabled(bool enabled); - static const int MsPerFrame = 17; + static const int MSecsPerFrame = 17; Ui::QmitkSimulationViewControls m_Controls; mitk::ISimulationService* m_SimulationService; - bool m_SelectionWasRemovedFromDataStorage; mitk::DataNode::Pointer m_Selection; + mitk::SimulationInteractor::Pointer m_Interactor; QTimer m_Timer; QTime m_NextRenderWindowUpdate; }; #endif diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui index 9c9e0516ee..0ece535e84 100644 --- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkSimulationViewControls.ui @@ -1,179 +1,186 @@ QmitkSimulationViewControls true 0 0 - 301 - 548 + 248 + 751 Simulation - - - false - - - Scene - - - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Animate - - - true - - - false - - - - - - - - 0 - 0 - - - - Step - - - - - - - - 0 - 0 - - - - Reset - - - - - - - - 0 - 0 - - - - dt - - - - - - - - 0 - 0 - - - - s - - - 3 - - - 0.010000000000000 - - - - - + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Animate + + + true + + + false + + + + + + + + 0 + 0 + + + + Step + + + + + + + + 0 + 0 + + + + Reset + + + + + + + + 0 + 0 + + + + dt + + + + + + + + 0 + 0 + + + + s + + + 3 + + + 0.010000000000000 + + + + - - - Surface Recording + + + Qt::Vertical - - - - - Record - - - true - - - - - - - false - - - Take Snapshot - - - - - - - 0 step(s) recorded - - - - + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + 1 + + + false + + + + Name + + + + + + true + + + 120 + + + + Property + + + + + Value + + + - - - Qt::Vertical + + + - - - 20 - 421 - - - + QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
+ + QmitkSceneTreeWidget + QTreeWidget +
QmitkSceneTreeWidget.h
+
+ + QmitkBaseTreeWidget + QTreeWidget +
QmitkBaseTreeWidget.h
+
diff --git a/Plugins/org.mitk.simulation/files.cmake b/Plugins/org.mitk.simulation/files.cmake index 43097f21ca..93637cdfb7 100644 --- a/Plugins/org.mitk.simulation/files.cmake +++ b/Plugins/org.mitk.simulation/files.cmake @@ -1,34 +1,31 @@ set(SRC_CPP_FILES - mitkExportMitkVisitor.cpp mitkGetSimulationPreferences.cpp mitkMeshMitkLoader.cpp ) set(INTERNAL_CPP_FILES - mitkGetDataStorage.cpp - mitkGetSimulationDataNode.cpp org_mitk_simulation_Activator.cpp ) set(MOC_H_FILES src/internal/org_mitk_simulation_Activator.h ) set(CACHED_RESOURCE_FILES resources/SOFAIcon.png ) set(QRC_FILES resources/Simulation.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach() foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach() diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetData.h b/Plugins/org.mitk.simulation/src/internal/mitkGetData.h deleted file mode 100644 index 8d97cc482c..0000000000 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetData.h +++ /dev/null @@ -1,53 +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. - -===================================================================*/ - -#ifndef mitkGetData_h -#define mitkGetData_h - -#include "mitkGetDataStorage.h" -#include - -namespace mitk -{ - template - typename T::Pointer GetData(const std::string& name) - { - DataStorage::Pointer dataStorage = GetDataStorage(); - - if (dataStorage.IsNull()) - return NULL; - - typename TNodePredicateDataType::Pointer predicate = TNodePredicateDataType::New(); - DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate); - - for (DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it) - { - DataNode::Pointer dataNode = it.Value(); - - if (dataNode->GetName() == name) - { - typename T::Pointer data = static_cast(dataNode->GetData()); - - if (data.IsNotNull()) - return data; - } - } - - return NULL; - } -} - -#endif diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp b/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp deleted file mode 100644 index 3a36bf5f87..0000000000 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetDataStorage.cpp +++ /dev/null @@ -1,34 +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 "mitkGetDataStorage.h" -#include "org_mitk_simulation_Activator.h" -#include - -mitk::DataStorage::Pointer mitk::GetDataStorage() -{ - IDataStorageService* dataStorageService = org_mitk_simulation_Activator::GetService(); - - if (dataStorageService != NULL) - { - IDataStorageReference::Pointer dataStorageReference = dataStorageService->GetDefaultDataStorage(); - - if (dataStorageReference.IsNotNull()) - return dataStorageReference->GetDataStorage(); - } - - return NULL; -} diff --git a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp b/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp deleted file mode 100644 index a4a37fa017..0000000000 --- a/Plugins/org.mitk.simulation/src/internal/mitkGetSimulationDataNode.cpp +++ /dev/null @@ -1,45 +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 "mitkGetDataStorage.h" -#include "mitkGetSimulationDataNode.h" -#include -#include - -mitk::DataNode::Pointer mitk::GetSimulationDataNode(sofa::core::objectmodel::BaseNode::SPtr rootNode) -{ - if (!rootNode) - return NULL; - - DataStorage::Pointer dataStorage = GetDataStorage(); - - if (dataStorage.IsNull()) - return NULL; - - TNodePredicateDataType::Pointer predicate = TNodePredicateDataType::New(); - DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate); - - for (DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it) - { - DataNode::Pointer dataNode = it.Value(); - Simulation::Pointer simulation = static_cast(dataNode->GetData()); - - if (simulation->GetRootNode() == rootNode) - return dataNode; - } - - return NULL; -} diff --git a/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp b/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp index 1b4b799983..edfa68046e 100644 --- a/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp +++ b/Plugins/org.mitk.simulation/src/mitkMeshMitkLoader.cpp @@ -1,140 +1,185 @@ /*=================================================================== 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 "internal/mitkGetData.h" +#include "internal/org_mitk_simulation_Activator.h" #include "mitkMeshMitkLoader.h" +#include +#include +#include #include #include #include #include #include #include +static mitk::DataStorage::Pointer GetDataStorage() +{ + mitk::IDataStorageService* dataStorageService = mitk::org_mitk_simulation_Activator::GetService(); + + if (dataStorageService != NULL) + { + mitk::IDataStorageReference::Pointer dataStorageReference = dataStorageService->GetDefaultDataStorage(); + + if (dataStorageReference.IsNotNull()) + return dataStorageReference->GetDataStorage(); + } + + return NULL; +} + +template +typename T::Pointer GetData(const std::string& name) +{ + mitk::DataStorage::Pointer dataStorage = GetDataStorage(); + + if (dataStorage.IsNull()) + return NULL; + + typename mitk::TNodePredicateDataType::Pointer predicate = mitk::TNodePredicateDataType::New(); + mitk::DataStorage::SetOfObjects::ConstPointer subset = dataStorage->GetSubset(predicate); + + for (mitk::DataStorage::SetOfObjects::ConstIterator it = subset->Begin(); it != subset->End(); ++it) + { + mitk::DataNode::Pointer dataNode = it.Value(); + + if (dataNode->GetName() == name) + { + typename T::Pointer data = static_cast(dataNode->GetData()); + + if (data.IsNotNull()) + return data; + } + } + + return NULL; +} + mitk::MeshMitkLoader::MeshMitkLoader() { this->addAlias(&m_filename, "dataNode"); this->addAlias(&m_filename, "surface"); } mitk::MeshMitkLoader::~MeshMitkLoader() { } bool mitk::MeshMitkLoader::canLoad() { Surface::Pointer surface = GetData(m_filename.getValue()); if (surface.IsNull()) return false; vtkPolyData* polyData = surface->GetVtkPolyData(); if (polyData == NULL || polyData->GetNumberOfCells() == 0) return false; return true; } bool mitk::MeshMitkLoader::load() { Surface::Pointer surface = GetData(m_filename.getValue()); vtkPolyData* polyData = surface->GetVtkPolyData(); // vtkSmartPointer transformFilter = vtkSmartPointer::New(); // transformFilter->SetTransform(surface->GetGeometry()->GetVtkTransform()); // transformFilter->SetInputConnection(polyData->GetProducerPort()); // transformFilter->Update(); // polyData = vtkPolyData::SafeDownCast(transformFilter->GetOutputDataObject(0)); sofa::helper::vector& positions = *this->positions.beginEdit(); sofa::helper::vector& edges = *this->edges.beginEdit(); sofa::helper::vector& triangles = *this->triangles.beginEdit(); sofa::helper::vector& quads = *this->quads.beginEdit(); sofa::helper::vector > polygons = *this->polygons.beginEdit(); vtkPoints* points = polyData->GetPoints(); vtkIdType numPoints = points->GetNumberOfPoints(); double point[3]; for (vtkIdType i = 0; i < numPoints; ++i) { points->GetPoint(i, point); positions.push_back(sofa::defaulttype::Vec3d(point[0], point[1], point[2])); } vtkCellArray* polys = polyData->GetPolys(); vtkIdType numPolys = polys->GetNumberOfCells(); vtkSmartPointer poly = vtkSmartPointer::New(); Edge edge; Triangle triangle; Quad quad; polys->InitTraversal(); while (polys->GetNextCell(poly) != 0) { switch (poly->GetNumberOfIds()) { case 1: break; case 2: edge[0] = poly->GetId(0); edge[1] = poly->GetId(1); edges.push_back(edge); break; case 3: triangle[0] = poly->GetId(0); triangle[1] = poly->GetId(1); triangle[2] = poly->GetId(2); triangles.push_back(triangle); break; case 4: quad[0] = poly->GetId(0); quad[1] = poly->GetId(1); quad[2] = poly->GetId(2); quad[3] = poly->GetId(3); quads.push_back(quad); break; default: sofa::helper::vector polygon; vtkIdType numIds = poly->GetNumberOfIds(); polygon.reserve(numIds); for (vtkIdType i = 0; i < numIds; ++i) polygon.push_back(poly->GetId(i)); polygons.push_back(polygon); break; } } this->positions.endEdit(); this->edges.endEdit(); this->triangles.endEdit(); this->quads.endEdit(); this->polygons.endEdit(); return true; }